2014-03-19 53 views
0

我有一組類用於存儲我目前正在嘗試實現深度複製機制的數據。爲此,我想在我的抽象類中定義一個方法deepCopy(),每個擴展類都需要實現。如何從它實現的類中確定方法的返回類型?

我在一個通用的方法定義的抽象方法讓每一位deepCopy()返回它在實現的類的對象掙扎。

public abstract class Foo { 
    public abstract Foo deepCopy(); 
} 

public class Bar extends Data { 
    @Override 
    public Bar deepCopy() { 
     //copying; 
    } 
} 

這是我想達到的目標,但我最終與此:

public abstract class Foo { 
    public abstract Foo deepCopy(); 
} 

public class Bar extends Data { 
    @Override 
    public Foo deepCopy() { 
     //copying; 
    } 
} 

打電話時deepCopy()這將導致一個錯誤:

public SomeClass extends Foo { 
    private Bar value; 

    private SomeClass(final SomeClass original) { 
     this.value = original.deepCopy(); // type-mismatch since deepCopy returns Foo but value is Bar. 
    } 

    @Override 
    public Foo deepCopy() { 
     return new SomeClass(this); 
    } 
} 

解決此問題的最簡單方法是將deepCopy的返回對象轉換爲Bar,但這看起來不對。

有沒有一種乾淨的方式來實現這一目標?

+0

除了它相當破碎的事實,使用'clone'有什麼問題? – Bathsheba

+0

@Bathsheba:每次我收集有關深拷貝對象的信息時,我都會讀到使用克隆應該避免的問題。 – padde

回答

0

仿製藥這似乎是協變返回類型將解決這裏的問題:

public abstract class Foo { 
    public abstract Foo deepCopy(); 
} 

然後Bar可以從方法返回一個Bar

public class Bar extends Foo { 
    @Override 
    public Bar deepCopy() { 
     //copying; 
    } 
} 

因此:

final Bar bar = new Bar(); 
final Bar barCopy = bar.deepCopy(); // <- Bar's deepcopy returns a Bar 
final Foo foo = ((Foo) bar).deepCopy(); // <- Foo's deepcopy returns a Foo 

將被允許因爲Bar extends Foo您可以使用Bar無論你將被允許使用Foo。所以一個子類可以覆蓋返回協變類型的超類的方法。

這會工作在更一般的情況:

public abstract class Foo { 
    public abstract Number getThing(); 
} 

public class Bar extends Foo { 
    @Override 
    public Integer getThing() { 
     //copying; 
    } 
} 

正如你所看到的,Bar.getThing返回Integer,但它會覆蓋它返回一個Number方法Foo.getThing。這很好,因爲我們可以使用Integer,只要我們可以使用Number

+0

哇。總是令我驚訝的是,事情可能有多簡單。謝謝,就是這樣。 – padde

0

你可以用Java中的Generics做到這一點。

像這樣實現類。

public abstract class Foo<Item> { 
    public abstract Item deepCopy(); 
} 

你可以閱讀這裏http://docs.oracle.com/javase/tutorial/java/generics/

+0

是的,我嘗試使用泛型,並結束與公共抽象類Foo 使用T作爲deepCopy()的返回值。但是,這個結束於擴展類,看起來像公共類Bar {},看起來很明顯是錯誤的。這只是我過於謹慎還是真的錯了? – padde

相關問題