2012-12-20 47 views
3

我有一個有幾個變量的體育基類。我還有幾個不同的課程,如排球,足球等,有其他方法和變量。他們看起來有點像這樣。如何將派生類傳遞給接受父類型的函數

public class Sport { 
    public String commonVar; 
    public Sport(String c) { 
     this.commonVar = c; 
    } 
} 

然後排球:

public class Volleyball extends Sport { 
    public String onlyVolleyball; 
    public Volleyball(String c, String thisVar) { 
     super(c); 
     this.onlyVolleyball = thisVar; 
    } 
} 

現在我要路過體育的派生類到一個函數在其他地方,但使得參數

public otherFunction(int one, int two, Sport sport) { } 

只有對待體育作爲運動對象(它會接受派生類,但是我不能訪問任何Sport不常見的變量和方法)。我的問題是如何創建一個函數,以便我可以發送所有類型的運動衍生物而不丟失任何數據?

回答

5

你不能,但你可以檢查對象實際上是擴展類的成員,然後將它轉換和使用它,如下所示:

public otherFunction(int one, int two, Sport sport) 
{ 
    if(sport instanceof Volleyball) 
    { 
     Volleyball volley = (Volleyball) sport; 
     //Do Volleyball things 
    } 
    else 
    { 
     //Only do sport things. 
    } 
} 
+0

我認爲這是我可能尋找的,有沒有辦法更自動地執行鑄造?我可以在運動中設置一個變量,如 'public class <?擴展體育> c;' 並在構造函數中從派生類中設置c。 – Ahorner

+1

@Ahorner實際上,除了具有擴展類型參數的類(例如'ArrayList ')之外,您不能動態轉換,因爲泛型聲明確保類型安全。如果你看看它的源代碼,你會看到'E'用來表示擴展類型,在'elementData()'方法中,該值被轉換爲'(E)elementData [index] ',但是這隻適用於這種情況,如果他們分享他們所有的方法。 (ArrayList soruce:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java) – MrLore

0

答案是,你不能。您需要將成員,可能是抽象方法(如getTypeOfSport())添加到基類中。

4

你不應該。如果該功能與抽象運動一起使用,那麼Sport所需的所有信息都應該可用。否則你應該真的有每個功能(或策略/處理程序或類似)。

您打破了面向對象原則中的開放閉合原則(SOLID中的O)。

你可以做到這一點雖然與instanceof檢查,然後抹上:

if (sport instanceof Volleyball) { 
    Volleyball v = (Volleyball)sport; 
} 
0

您正在處理的「表達問題」;它很難解決。有一兩件事你可以做的是這樣的:

public interface SportFunction { 
    void doChessFunction(Chess sport); 
    void doVolleyballFunction(Volleyball sport); 
} 

public abstract class Sport { 
    public String commonVar; 
    public Sport(String c) { 
     this.commonVar = c; 
    } 
    public abstract void doSportFunction(SportFunction function); 
} 

public class Volleyball extends Sport { 
    public String onlyVolleyball; 
    public Volleyball(String c, String thisVar) { 
     super(c); 
     this.onlyVolleyball = thisVar; 
    } 

    public void doSportFunction(SportFunction function) { 
     function.doVolleyballFunction(this); 
    } 
} 

public class Chess extends Sport { 
    public int onlyChess; 
    public Chess(String c, int thisVar) { 
     super(c); 
     this.onlyChess = thisVar; 
    } 

    public void doSportFunction(SportFunction function) { 
     function.doChessFunction(this); 
    } 
} 

然後使用類這樣的:

public void otherFunction(int one, int two, Sport sport) { 
    sport.doSportFunction(new OtherSportFunction(one, two)); 
} 

public class OtherSportFunction implements SportFunction { 
    public OtherSportFunction(int one, int two) { /* do stuff */ } 
    public void doChessFunction(Chess sport) { /* do chess stuff */ } 
    public void doVolleyballFunction(Volleyball sport) { /* do volleyball stuff */ } 
} 
1

基本上,解決問題的方法取決於你到底想實現。

與此同時,考慮到您的文章,在我看來,你正試圖混合不同的職責,它們是:

  1. 處理運動情況。
  2. 處理Sport實例的衍生物。

可能這意味着您的方法根本不需要運動實例。 它實際需要的是訪問特定的運動。如我錯了請糾正我。

因此最簡單的解決辦法是宣佈otherFunction像以下:

public otherFunction(int one, int two, VolleyBall sport) 
public otherFunction(int one, int two, Soccer sport) 
public otherFunction(int one, int two, BasketBall sport) 
public otherFunction(int one, int two, AnyOtherAwsomeSport sport) 

這樣你都清楚地告訴什麼樣的運動您的函數處理 而且你有非常清晰的界面,很容易理解和維護。

+0

你在這個假設中是正確的。不過,我認爲在這種情況下'instanceof'可能會佔用較小的代碼。 – Ahorner

相關問題