[英]Question on the nature of inherited Java classes
所以我認為我有一個非常基本的問題。 假設您的項目com.bee.buzz中包含一個名為com.cow.moo的開源Java程序。
moo有很多很棒的課程,其中大部分是你不想觸摸的,但是有一些你做的。 現在,在這一點上,最好的辦法是擴展你想要修改的類,對吧? (我知道有很多關於擴展與實現的說法,但這些類都不是接口,所以這是不可能的。)
我的問題是,說這是moo中的類:
package com.cow.moo;
public class Milk {
private float currentMilk;
public int getMilk() { /* Stuff */ }
public float convertToGallons (float liquid) { /* More Stuff */ }
}
現在,假設我想在擴展Milk的新類中使用getMilk。 但是,Milk中的getMilk依賴於私有變量(如currentMilk)和其他我不會包含的函數(如convertToGallons。)如果我希望我的新函數正常工作,我是否必須包含其他變量和函數? 我不想大量修改函數,只需添加一點就可以了。 最好的方法是什么?
一般來說,建立一個更大的項目的提示也是有用的。 我認為這里的一些Java專家甚至不會花五秒鍾來得出答案。 謝謝你的時間。
一般建議是贊成合成而不是繼承 。
比如說,你有一個接口和一個現有的實現,大多數符合你的需要,比如
public interface MilkProvider { public float getMilk(); }
public class Milk implements MilkProvider { // same as you example }
並需要另一個自定義實現,你可以這樣編碼:
public class MyMilk implements MilkProvider {
private MilkProvider milk;
public MyMilk(int someValue) {
milk = new Milk(someValue); // unfortunatly we can't get rid of a depencency
// to the concrete class because we need to create
// something. An existing factory could help, but
// but usually there's none implemented.
}
public float getMilk() {
float result = milk.getMilk();
// do somethink with the result
return float;
}
}
我認為在這種情況下,更好的解決方案將是多態(靜態多態),或者您可以使用反射( 不要使用這種方式 )來訪問私有變量。
現在,假設我想在擴展Milk的新類中使用getMilk。 但是,Milk中的getMilk依賴於私有變量(如currentMilk)和其他我不會包含的函數(如convertToGallons。)如果我希望我的新函數正常工作,我是否必須包含其他變量和函數?
您不必包含公共函數和變量。 繼承的核心概念是,作為子類,您可以免費獲得子類中包含的所有父類的公共(和受保護)成員。 所以你的子類(比如說HoneyMilk)可以從一開始就調用convertToGallons
。
在這種情況下重寫getMilk
會非常棘手,因為它依賴於私有變量(您的子類無法訪問)。 我的建議是將你的思維方式從把班級視為“白盒子”轉變為“黑匣子”。 我的意思是你應該實現你的被覆蓋版本的getMilk
,就好像你實際上看不到Milk的源代碼一樣。 雖然它可能看起來像一個迂回的解決方案(我的意思是,為什么我不能在這里調整這一行?!),這將迫使你只使用父類公開公開的子類來實現你的子類。 它還強調抽象的重要性,這對於開發大型項目絕對至關重要。
如果它們是公共的,您可以通過方法訪問器(getter和setter)擴展類和訪問實例變量。
您可以使用AOP(面向方面編程)在運行時更改moo類,而無需更改其源。
請仔細閱讀一些“ 組合與繼承”主題 。
希望這會幫助你。
除非你使用丑陋的Java反射,否則你將無法使用私有類成員。 如果我是你(並且更改不是太重,在這種情況下我會分叉原始項目),我會考慮在運行時修改代碼或靜態使用方面編織(面向方面編程)。 AspectJ可能看起來好像有一個很好的學習曲線,但它是一個很好的工具,可以在你的工具箱中完美匹配你的需求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.