2013-08-22 99 views
8

我面臨this question中描述的問題,但希望找到一個解決方案(如果可能),沒有所有的強制轉換和@SuppressWarning註釋。繼承的方法返回的引用類型

更好的解決方案將是一個通過在引用的一個構建:

  • 去除@SuppressWarning
  • 去除石膏
這裏提出將2點進行分級

解決方案基礎上,標準。如果有兩個以上的積分,Bounty會用大多數積分或「最優雅」積分來解決問題。

+0

將在2天內因SO機制,增加賞金提供賞金。儘管現在請隨時張貼您的答案。 – pnt

+0

相關:[有沒有辦法用類型變量引用當前類型?](http://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current -type-variable) –

回答

9

沒有演員,沒有@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; 
    } 
} 
+1

這被選爲最好的答案,因爲它完全避免了強制轉換,沒有@SuppresWarnings,根據我的說法,它是最優雅的,因爲它也避免了方法重寫(您必須「重寫」的引用看起來更清晰並且需要更少的代碼;它對用戶來說也是隱藏的,你可以覆蓋任何東西)。將在23小時內獎賞賞金。 – pnt

+0

@pnt這與您引用問題中接受的答案基本相同。你爲什麼不喜歡它並在這裏接受它? –

+1

@FrancoisBourgeois其實,這不是同一個解決方案。在另一種解決方案中,在抽象類中使用'return(T)';在編譯時編譯器無法知道轉換是否安全(即使它可以,只有開發人員知道),因此需要@SuppressWarning註釋。在我的解決方案中,由於'that'直接在子類中設置,因此不需要投射。這個* no-cast解決方案*精確地在這裏被問到。 – sp00m

1

一種解決方案是重寫子類中的方法,並將返回類型更改爲更具體的方法,即。孩子的類型。這需要鑄造。而是採用了典型(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; 
} 
+0

不是一個真正的解決方案,因爲它不會刪除轉換(只是將它們隱藏並隱藏起來),並不能解決引用問題中的原始問題。是的,當然你可以重寫方法來返回一個更具體的類型,但是重點是重用它,而不必在每個孩子中重寫它。 – pnt

+0

@pnt所陳述的問題是_I想要實現這個,而不使用額外的接口和額外的方法,並使用它沒有類轉換,輔助參數等等._事情是你不能。所提出的解決方案都有額外的方法和/或額外的參數。要麼覆蓋有問題的方法,要麼在父項中引入另一個方法並覆蓋該方法。在泛型解決方案中,您還需要引入一個類型參數。 –

5

一種方法是在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幾天後就學會了這個技巧。

參考:

+1

您可能想要聲明「Parent >'。否則,你可以'擴展Parent ',並且方法鏈接將以'String getThis()'結束。 –

+0

@SotiriosDelimanolis。啊!對。謝謝:) –