2013-12-17 75 views
5

比方說,我有標準的Draw類和Circle和Square的繼承類。有沒有辦法做到以下幾點?也許用泛型?實現基類方法的java方法能返回一個繼承類嗎?

class Draw { 
    public abstract Draw duplicate(); 
} 

class Circle extends Draw { 
    public Circle duplicate() { 
    return new Circle(); 
    } 
} 

class Square extends Draw { 
    public Square duplicate() { 
    return new Square(); 
    } 
} 
+0

繪製應該是一個抽象類。否則它看起來很好 – k2col

回答

4

是的,可以有一個覆蓋方法返回一個類型,該類型是超類方法返回類型的子類。這種稱爲「協變返回類型」的技術被描述爲at the bottom of a Java tutorial on return types。這是有效的,因爲CircleSquareDraw s,所以即使你有一個超類參考,並且你不知道或關心你真的有哪個子類,你仍然可以保證返回Draw。順便提一下,爲了讓你的代碼編譯,你只需要製作Drawabstract。其他一切,包括協變返回類型,看起來都很好。

+0

哦哇,這是超級簡單。這是永遠在Java中的缺點,你不知道這些新事情發生的時間。謝謝。 –

4

是的,你可以因爲Java 5的

由於Java 5,子類中的方法可能會返回一個對象,其類型是方法與在相同簽名的返回類型的子類超類。 (source)。這被稱爲協變返回類型。

1

我會在這裏使用泛型:

class Draw<T> { 
    public abstract T duplicate(); 
} 

class Circle extends Draw<Circle> { 
    @Override 
    public Circle duplicate() { 
    return new Circle(); 
    } 
} 

class Square extends Draw<Square> { 
    @Override 
    public Square duplicate() { 
    return new Square(); 
    } 
} 
+0

嘿亞歷克斯,你可以擴展爲什麼你會使用泛型?看起來多餘。 – bcorso

+0

基於超類沒有泛型的類型安全實用方法... –

+0

類似於'public static > T duplicate(T draw){return draw.duplicate(); } –

1

我想你想要做的是以下幾點:

public abstract class Draw<T extends Draw> { 
    public abstract T duplicate(); 
} 

public class Circle extends Draw<Circle> { 
    @Override 
    public Circle duplicate() { 
     return new Circle(); 
    } 
} 

public class Square extends Draw<Square> { 
    @Override 
    public Square duplicate() { 
     return new Square(); 
    } 
} 
  1. T使用仿製藥的(有限制,應延長Draw,以避免奇怪的遺傳,如Circle extends Draw<List>
  2. 添加abstract關鍵字在Draw

然後,您可以執行以下操作:

Square originalSquare = new Square(); 
Circle originalCircle = new Circle(); 

Square duplicatedSquare = originalSquare.duplicate(); 
Circle duplicatedCircle = originalCircle.duplicate(); 

編輯

沒有仿製藥,你可以做這樣的事情:

public abstract class Draw { 
    public abstract Draw duplicate(); 
} 

public class Circle extends Draw { 
    @Override 
    public Circle duplicate() { 
     return new Circle(); 
    } 
} 

public class Square extends Draw { 
    @Override 
    public Square duplicate() { 
     return new Square(); 
    } 
} 

感謝Pavel,rgettman和Enno Shioji,我不知道「協變返回類型」。

+0

你真的讀過其他的答案嗎?你可以在不使用泛型的情況下做你正在描述的內容。 –

+0

在寫我自己的答案之前,我還沒有看到其他答案。我不知道協變返回類型,謝謝。 – ssssteffff