2015-03-13 79 views
0

我不確定從父代到子代向下轉換或從A中創建B(​​)的最佳做法是什麼。使用父配置實例化子對象或「向父代父子代」

作爲一個例子,我有兩個類:

父之一:

public class SoccerPlayer { 

    private String name; 
    private SoccerShoe shoe; 
    private SoccerJersey jersey; 
    /* ... */ 
} 

那孩子一個:

public class Goalkeeper extends SoccerPlayer { 

    private GoalkeeperGlove glove; 
    /* ... */ 
} 

現在一個普通的足球球員想成爲一名球員守門員。我能做什麼?顯然,以下是行不通的:

SoccerPlayerArrayOfTeamA[0] = new SoccerPlayer("Robert"); 

    /*... new career path ...*/ 

    SoccerPlayerArray[0] = (Goalkeeper) SoccerPlayerArray[0] 

但是,這是我要說的話「我想要做」 ...
子類(Goalkeeper)的新實例所應有的一切變量配置如舊父類的實例(SoccerPlayer)。 (例如name,jersey ...) 是否有OOP的方式來做,我必須手動設置每個變量,如下所示?

/*... new career path ...*/ 

    SoccerPlayer temp = SoccerPlayerArray[0] 
    SoccerPlayerArray[0] = new Goalkeeper(temp.getName()); 
    SoccerPlayerArray[0].setJersey(temp.getJersey()); 
+2

如果您需要動態更改對象的類型,則您的面向對象設計是錯誤的。一個對象始終是同一個類的一個實例。它的類型不能改變。從一開始它就是一名守門員或一名球員。 – 2015-03-13 12:47:34

+1

@Magnamag這是一個好點!它是一個複雜系統的一部分,但我會嘗試更改創建過程 – Robert 2015-03-13 13:21:53

回答

2

結帳裝飾設計模式。例如。 Java IO類。

當任何對象動態地想改變它的行爲,那麼你可以用所需的對象包裝該對象。就像C wants to become B那麼B應該有一個接受C的構造函數,然後B中的方法應該在適當的時候使用C.最好的例子是當FileInputStream wants to become BufferedInputStream你可以通過在其構造函數中傳遞FileInputStream來創建BufferedInputStream,但它不需要複製FileInputStream的屬性。

+1

這對我有幫助嗎?你能否詳細說明一下?當'B實現A'(Goolkeeper實現玩家)和'C實現A'(Soccerplayer implements玩家)時,我不能將C轉換爲B(Soccerplayer to Goalkeeper)... – Robert 2015-03-13 13:18:58

+1

當任何對象動態地想改變它的行爲時您可以用所需的對象包裝該對象。就像'C想成爲B'一樣,B應該有一個接受C的構造函數,然後B中的方法應該在適當的時候使用C.最好的例子是當'FileInputStream想要成爲BufferedInputStream'時,你可以通過在其構造函數中傳遞FileInputStream來創建'BufferedInputStream',但它不需要複製'FileInputStream'的屬性。 – hemant1900 2015-03-13 14:37:46

+0

啊,好吧,這很有道理!謝謝! – Robert 2015-03-13 15:09:02

1

將一個拷貝構造函數添加到接受SoccerPlayer作爲參數的守門員。

+0

但是,我必須在複製構造函數中手動設置每個變量,對吧? – Robert 2015-03-13 13:08:13

+0

是的。有周圍沒有真正的方法。但這是在一個地方。 – Necreaux 2015-03-13 13:11:32