[英]What are the differences between these methods to access other classes in Java?
目前,我正在從事Java開發,並且正在努力理解實例和具有這種性質的事物的概念。 當我有一個變量或方法時,我需要在另一個類中訪問,目前
public class Class1 implements Listener {
private final Main main;
private final Class2 class2;
public Class1(Main main, Class2 class2) {
this.main= main;
this.class2 = class2;
}
我應該提到我正在嘗試開發一個Minecraft插件,因此Listener類必須實現Listener。 但是,當我嘗試為需要引用2個類的類注冊事件(同樣,這是Minecraft的另一件事)時,代碼變得混亂。 例如,要獲取引用另外2個其他類的類,則eventRegister可能如下所示:(在主類中)
pm.registerEvents(new ClassX(this, new ClassY(this, new ClassZ(this))), this);
(注冊事件需要一個偵聽器和一個主類)
我的問題問:獲取另一個類並簡單地擴展它的方法之間有什么區別? 有區別嗎?
擴展類時,您將應用繼承。 您將可以從超類訪問所有public
方法。
實現接口時,您要簽訂合同,必須從該接口實現所有非默認方法。
當您將一個實例傳遞到另一個實例(通過您的實例中的構造函數)時,您正在應用對象合成 ,這類似於說“我將把這台特定的引擎放入這輛特定的汽車”。 您可能希望將不同的引擎放入另一輛汽車,因此您將傳遞不同的引擎作為構造函數。
該implements
稱為繼承 。 繼承的思想是知道所有類都是同一類 。 例如,您可能會說“所有汽車都可以turnLeft()和turnRight()”,因此,如果有人想創建自己的汽車(或者在您的情況下,他們自己的插件),那么他們的汽車也需要能夠turnRight()
和turnLeft()
。
讓我們回到您的問題。 如果看到一段看起來“通用”的代碼,則可能需要將通用部分提取到其自己的類中,然后繼承該類。 例如,“所有動物都可以shout()
”或“所有工具都可以use()
-d”。 但是,如果您想讓這只鴨子了解那只鴨子-您需要參考另一只鴨子中的一只鴨子。
但是,這並不意味着您需要使用構造函數。 構造函數用於對象不能沒有的引用(不能處於有效狀態)。 例如, new Duck(new DuckBrain())
有意義,但是new Duck(new Duck())
沒有意義。 對於這些情況,您可能會引入setter (在鏈接中搜索Java示例)。 設置器是更改對象包含內容的方法。
不必給類一個您需要的每件事的實例,而是給它一個存儲它們的對象。 在您的情況下,它可能是您插件的主類。
class ClassA implements Listener {
private final MyPlugin plugin;
public ClassA(MyPlugin plugin) {
this.plugin = plugin;
}
}
只要確保使用訪問修飾符或獲取器就可以從ClassA
訪問MyPlugin
中的所有內容。
您一直在做的事情是完全正常的,並且受到鼓勵。 沒有明確設計繼承的過度使用會導致錯誤的代碼。
您還通過構造函數傳遞了每個類的需求,這也是一種良好的實踐,稱為“依賴注入”,它有助於更好的測試和編寫單元測試。
對於高級項目,通常使用Dependency Injection框架來管理將您的依賴項傳遞到許多類中,但是對於小插件來說,則不必要。
根據這些類的可重用性,您可能希望為其創建一些接口。
如果使用依賴注入構造類變得很麻煩,那么您可以研究幾種模式來提供幫助。
工廠模式和構建器模式在整個行業中得到廣泛使用,這取決於構造的對象得到的頻率,復雜程度和變化程度。
創建的復雜對象通常很適合Factory模式 。
具有高可變性的簡單對象很適合構建器模式 。
如果通過構造函數傳遞所有內容變得困難,則始終可以在構造后初始化對象,但這會產生維護成本,因為您需要確保正確初始化了對象。
為什么您的class1需要引用class2? 它是對象還是OO編程中的某物,這意味着您的代碼將變得非常夫婦,這是一個糟糕的設計,您應該使用其他設計模式來使您的代碼解耦,即Class1不應依賴Class2。
回到您的問題,通過構造函數傳遞對象與擴展傳遞對象有什么區別?
當您擴展一個類時,您可以覆蓋母類中的某些方法,即Dog extends Animal
或者甚至可以在您的超類中調用該方法(通過super.method()
的Animal類)。
在這種情況下,當您通過構造函數傳遞對象時,可以在通過構造函數傳遞的對象中使用該對象。
減少代碼混亂的最好方法是我建議使用偵聽器模式(pub子程序),例如https://github.com/greenrobot/EventBus之類的現有庫,您可以在其中創建事件,例如可以在播放器中創建事件如果您創建了另一個訂閱該事件的類,那么當事件發生時,它將通知所有訂閱者觸發一個函數。 現在,您無需將所有類都耦合在一起。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.