當從子類對象調用此方法時,是否有任何優雅的方法可以使Java方法位於子類的父類返回對象中?如何讓Java父類方法返回子類的對象
我想在不使用其他接口和額外方法的情況下實現此功能,並且不使用類轉換,輔助參數等等。
更新:
對不起,我是不太清楚。我想要實現方法鏈,但我有父類方法的問題:當我調用父類方法時,我失去對子類方法的訪問... 我想我已經提出了我的核心理念。
所以方法應該返回this
對象this.getClass()
類。
當從子類對象調用此方法時,是否有任何優雅的方法可以使Java方法位於子類的父類返回對象中?如何讓Java父類方法返回子類的對象
我想在不使用其他接口和額外方法的情況下實現此功能,並且不使用類轉換,輔助參數等等。
更新:
對不起,我是不太清楚。我想要實現方法鏈,但我有父類方法的問題:當我調用父類方法時,我失去對子類方法的訪問... 我想我已經提出了我的核心理念。
所以方法應該返回this
對象this.getClass()
類。
如果你只是在尋找方法鏈接對定義的子類,那麼下面應該工作:
public class Parent<T> {
public T example() {
System.out.println(this.getClass().getCanonicalName());
return (T)this;
}
}
如果你喜歡,那麼指定通用返回類型的一些子對象可能是抽象的(這意味着你不能從ChildA訪問childBMethod):
public class ChildA extends Parent<ChildA> {
public ChildA childAMethod() {
System.out.println(this.getClass().getCanonicalName());
return this;
}
}
public class ChildB extends Parent<ChildB> {
public ChildB childBMethod() {
return this;
}
}
,然後你使用這樣
public class Main {
public static void main(String[] args) {
ChildA childA = new ChildA();
ChildB childB = new ChildB();
childA.example().childAMethod().example();
childB.example().childBMethod().example();
}
}
輸出將是
org.example.inheritance.ChildA
org.example.inheritance.ChildA
org.example.inheritance.ChildA
org.example.inheritance.ChildB
org.example.inheritance.ChildB
我確切地知道你的意思,在Perl中有$class
變量,這意味着如果你在子類上調用一些工廠方法,即使它沒有在子類中重寫,如果它實例化任何$class
實例子類將被創建。
Smalltalk,Objective-C,許多其他語言都有類似的功能。
唉,在Java中沒有這樣的等效工具。
在Perl中,根本不存在通用的內置'$ class'變量。它可以通過檢索類方法的第一個參數(例如,MyClass-> mySub()調用作爲第一個參數傳遞MyClass)或者通過獲取object(這是調用對象的方法的第一個參數,例如'$ myclass_object-> mySub()'調用將'$ myclass_object'作爲第一個參數,'ref($ myclass_object)'返回'「MyClass」') 。請知道你在說什麼。 – DVK 2010-10-27 10:08:01
但是,正如你所說,類方法的第一個參數始終是該方法應用於的類的名稱。這意味着您可以編寫方法,然後執行'$ class-> newInstance()',如果在子類上調用該方法,將會創建子類的實例。用於工廠方法,施工中的模板方法模式等等。在Java中,即使調用MySubObj.newInstance(),靜態MyObj newInstance(){..}也將總是生成一個MyObj,並且沒有任何方法可以解決這個問題。在Perl中。 – 2010-10-27 12:14:23
只需證明:
public Animal myMethod(){
if(this isinstanceof Animal){
return new Animal();
}
else{
return this.getClass().newInstance();
}
}
隨着子類的添加,更改和刪除,此方法必須一次又一次地更改。儘管如此,仍然是一個解決方案。 – BoltClock 2010-10-27 09:58:32
@BoltClock,剛剛證明,我已經解決了您在此更新中的問題。 – 2010-10-27 10:02:49
您可以撥打this.getClass()
獲得運行時類。
但是,這不一定是調用該方法的類(它可能會更進一步向下)。
而且您需要使用反射來創建新的實例,這很棘手,因爲您不知道子類具有哪種類型的構造函數。
return this.getClass().newInstance(); // sometimes works
聽起來像:父母可以通過反思產生一個孩子,但不能保證是他的。 :) – 2010-10-27 10:35:15
它將成爲當前類的一個子類,因爲「this」總是。不過,它可能是一個間接的子類。 – Thilo 2010-10-28 01:12:19
public class Parent {
public Parent myMethod(){
return this;
}
}
public class Child extends Parent {}
並調用它像
Parent c = (new Child()).myMethod();
System.out.println(c.getClass());
這個解決辦法是正確的?如果是,那麼它與第一種解決方案有什麼不同?
你想達到什麼目的?這聽起來像個不好的主意。家長不應該對其子女有任何瞭解。看起來非常接近打破Liskov Substitution Principle。我的感覺是,通過改變總體設計可以更好地服務您的用例,但是如果沒有更多信息,很難說。
抱歉聽起來有點迂腐,但是當我看到這樣的問題時,我有點害怕。
非常感謝。這正是我想要的。 – 2010-10-27 13:16:26
@Errandir沒問題 - 很高興幫助 – 2010-10-27 13:17:22
完美。但是我需要將'@SuppressWarnings(「unchecked」)'添加到'example()'中。 – 2012-10-01 02:52:10