我面臨this question中描述的問題,但希望找到一個解決方案(如果可能),沒有所有的強制轉換和@SuppressWarning註釋。繼承的方法返回的引用類型
更好的解決方案將是一個通過在引用的一個構建:
- 去除@SuppressWarning
- 去除石膏
解決方案基礎上,標準。如果有兩個以上的積分,Bounty會用大多數積分或「最優雅」積分來解決問題。
我面臨this question中描述的問題,但希望找到一個解決方案(如果可能),沒有所有的強制轉換和@SuppressWarning註釋。繼承的方法返回的引用類型
更好的解決方案將是一個通過在引用的一個構建:
解決方案基礎上,標準。如果有兩個以上的積分,Bounty會用大多數積分或「最優雅」積分來解決問題。
沒有演員,沒有@SuppressWarning,幾行只:
public abstract class SuperClass<T extends SuperClass<T>> {
protected T that;
public T chain() {
return that;
}
}
public class SubClass1 extends SuperClass<SubClass1> {
public SubClass1() {
that = this;
}
}
public class SubClass2 extends SuperClass<SubClass2> {
public SubClass2() {
that = this;
}
}
這被選爲最好的答案,因爲它完全避免了強制轉換,沒有@SuppresWarnings,根據我的說法,它是最優雅的,因爲它也避免了方法重寫(您必須「重寫」的引用看起來更清晰並且需要更少的代碼;它對用戶來說也是隱藏的,你可以覆蓋任何東西)。將在23小時內獎賞賞金。 – pnt
@pnt這與您引用問題中接受的答案基本相同。你爲什麼不喜歡它並在這裏接受它? –
@FrancoisBourgeois其實,這不是同一個解決方案。在另一種解決方案中,在抽象類中使用'return(T)';在編譯時編譯器無法知道轉換是否安全(即使它可以,只有開發人員知道),因此需要@SuppressWarning註釋。在我的解決方案中,由於'that'直接在子類中設置,因此不需要投射。這個* no-cast解決方案*精確地在這裏被問到。 – sp00m
一種解決方案是重寫子類中的方法,並將返回類型更改爲更具體的方法,即。孩子的類型。這需要鑄造。而是採用了典型(Child)
鑄造,使用Class#cast(Object)
方法
public class Parent {
public Parent example() {
System.out.println(this.getClass().getCanonicalName());
return this;
}
}
public class Child extends Parent {
public Child example() {
return Child.class.cast(super.example());
}
public Child method() {
return this;
}
}
演員的標準方法中隱藏。來自Class
。
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
return (T) obj;
}
不是一個真正的解決方案,因爲它不會刪除轉換(只是將它們隱藏並隱藏起來),並不能解決引用問題中的原始問題。是的,當然你可以重寫方法來返回一個更具體的類型,但是重點是重用它,而不必在每個孩子中重寫它。 – pnt
@pnt所陳述的問題是_I想要實現這個,而不使用額外的接口和額外的方法,並使用它沒有類轉換,輔助參數等等._事情是你不能。所提出的解決方案都有額外的方法和/或額外的參數。要麼覆蓋有問題的方法,要麼在父項中引入另一個方法並覆蓋該方法。在泛型解決方案中,您還需要引入一個類型參數。 –
一種方法是在Parent
類定義一個抽象方法getThis()
,並且使所有的Child
類覆蓋它,並返回所this
參考。這是恢復類層次結構中對象類型this
的一種方法。
的代碼應該是這樣的:
abstract class Parent<T extends Parent<T>> {
protected abstract T getThis();
public T example() {
System.out.println(this.getClass().getCanonicalName());
return getThis();
}
}
class ChildA extends Parent<ChildA> {
@Override
protected ChildA getThis() {
return this;
}
public ChildA childAMethod() {
System.out.println(this.getClass().getCanonicalName());
return this;
}
}
class ChildB extends Parent<ChildB> {
@Override
protected ChildB getThis() {
return this;
}
public ChildB childBMethod() {
return this;
}
}
public class Main {
public static void main(String[] args) throws NoSuchMethodException {
ChildA childA = new ChildA();
ChildB childB = new ChildB();
childA.example().childAMethod().example();
childB.example().childBMethod().example();
}
}
按規定,沒有鑄造並沒有@SuppressWarnings。我從Angelika Langer - Java Generics FAQs幾天後就學會了這個技巧。
參考:
您可能想要聲明「Parent
@SotiriosDelimanolis。啊!對。謝謝:) –
將在2天內因SO機制,增加賞金提供賞金。儘管現在請隨時張貼您的答案。 – pnt
相關:[有沒有辦法用類型變量引用當前類型?](http://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current -type-variable) –