2015-11-24 49 views
1

我在Android Studio中創建了一個遊戲。遊戲具有簡易模式和硬模式(分別爲hard=Falsehard=True)。Java/Android:定義未知類型的對象

Easy模式和Hard模式都有它們自己的類別。這兩個類都包含相同的功能,但它們的實現有所不同。我從我的Gameplay類調用這些類中的函數。這意味着,在我的遊戲類的每一個功能,我必須做到以下幾點:不是每個函數執行此的if-else檢查

if (hard == True): 
    HardGameplay gameplayMode = new HardGameplay(); 
else: 
    EasyGameplay gameplayMode = new EasyGameplay(); 

functionResult = gameplayMode.myFunction(); 

不過,我想檢查這只是一次。因此,我創建了一個checkDifficulty()函數,我在的onCreate開始撥打:

public ??? gameplayMode; 
public Boolean easyOrHard() { 
    if (hard == True): 
     HardGameplay gameplayMode = new HardGameplay(); 
    else: 
     EasyGameplay gameplayMode = new EasyGameplay(); 
} 

的問題是,我不知道我應該在???放置什麼類型。它應該是HardGameplayEasyGameplay,但我不知道這兩個提前。把Object也沒有工作,因爲那樣,我打電話給每個功能給出錯誤Cannot resolve method 'myFunction()'

有誰知道該怎麼辦?或者,我忽略了一個更簡單的實現?任何幫助是極大的讚賞!

+0

看看[策略模式](https://en.wikipedia.org/wiki/Strategy_pattern) –

回答

6

您需要多態性。

因此,創建一個名爲GamePlay的超類,並使HardGamePlayEasyGamePlay擴展這些類。這種超定義了將通過其子類

public abstract class GamePlay { 
    public abstract void myFunction(); 
} 

public class HardGamePlay extends GamePlay { 
    public void myFunction() { 
     //your code here 
    } 
} 

來實現,那麼你可以使用

public GamePlay gamePlayMode 

在你GameActivity做到這一點的功能:

Gameplay gameplay = null; 
if (hardmode) 
    gameplay = new HardGamePlay(); 
else 
    gameplay = new EasyGamePlay(); 
+0

這看起來似乎是解決我的問題的最有效的方法,謝謝!但是,有一個小問題。我在Android Studio中這樣做,我的Gameplay.java類是從我的GameplayActivity.java調用的:Gameplay gameplay = new Gameplay(); gameplay.initializeGame(this,this.getApplicationContext());'。但是,不可能實例化一個抽象類。有沒有解決的辦法? –

+0

你必須實例化子類。 '遊戲gameplay =新的HardGamePlay();'。 –

4

您只需要使用一個接口:

public interface GamePlay { 
    ... // Your different methods declaration 
} 

你的兩個類將實現這個接口:

public class HardGamePlay implements GamePlay { 
    ... // You override the methods here 
} 

public class EasyGamePlay implements GamePlay { 
    ... // You override the methods here 
} 

然後,您可以使用:

GamePlay gamePlayMode = easyOrHard(); 
public GamePlay easyOrHard() { 
if (hard) { 
    return new HardGameplay(); 
} else { 
    return new EasyGameplay(); 
} 

這就是所謂的Polymorphismhttp://www.artima.com/objectsandjava/webuscript/PolymorphismInterfaces1.html

+0

當我嘗試將最後一個代碼塊添加到'public interface GamePlay'時,它給了我兩個錯誤:'變量'gamePlayMode'可能未被初始化'和'接口方法不能有主體'。我究竟做錯了什麼? –

+0

對於你的第一點,我忘了將變量'gamePlayMode'初始化爲'null'(回答編輯)。一個接口不能包含代碼,它只是用來聲明你的方法。代碼將寫入實現該接口的類中,即在'HardGamePlay'和'EasyGamePlay'中。 – Patrick

3

如果這兩個類將包含相同的方法,你可以簡單地創建一個Game接口,您可以將其用作變量類型。

public interface Game { 
    void methodA(); 
    void methodB(); 
} 

兩種模式現在可以從這個接口

public class HardGameplay implements Game{ 
    @Override 
    public void methodA() { 
     // Do something 
    } 

    @Override 
    public void methodB() { 
     // do something 
    } 
} 

public class EasyGameplay implements Game{ 
    @Override 
    public void methodA() { 
     // Do something 
    } 

    @Override 
    public void methodB() { 
     // do something 
    } 
} 

實現您現在可以創建一個變量Game並指定特定類型的模式,它的。由於他們兩人有你仍然可以存取權限兩個類以同樣的方式通用的接口,因爲它可以在該方法中可以看出doSomethingHere

public class GamePlayManager { 
    private boolean hardMode; 

    private Game gameMode; 

    public GamePlayManager(boolean hardMode) { 
     this.hardMode = hardMode; 
    } 

    public void createGame() { 
     if(hardMode) { 
      gameMode = new HardGameplay(); 
     } else { 
      gameMode = new EasyGameplay(); 
     } 
    } 

    public void doSomethingHere() { 
     gameMode.methodA(); 
    } 

} 
1

正如西蒙說,你可以創建一個正被擴展HardGamePlayEasyGamePlay。如果兩個類都有相同的方法術語,這將起作用。

但是,如果EasyGamePlay和HardGamePlay類有不同的方法,你可以嘗試使用對象,但要記住,你需要調用方法前投它的適當的類

public class Person { 
    public void sayHello() { 
     System.out.println("I am a person"); 
    } 
} 

public class Dog { 
    public void bark() { 
     System.out.println("Woof!"); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     Object thing = new Dog(); 

     //This won't work as the program 
     //does not know which instance to call 
     //thing.bark(); 

     if(thing instanceof Person) { 
      ((Person)thing).sayHello(); 
     } else if(thing instanceof Dog) { 
      ((Dog)thing).bark(); 
     } 
    } 
} 

而且還在,去最好的辦法是使用多態性使您避免使用對象變量/場。如果不能使用多態考慮審查軟件架構

2

基本上你有2個回答上面至今:

1)使用抽象基類抽象myFunction的()

2)有myFunction的一個共同的接口()EasyGameplay和HardGameplay實現

您在兩種方法之間決定的方式是兩種方法之間有多少通用的實現數據和行爲:如果至少有一個方法實現(不只是方法簽名)可以共享和/或者類具有相同的類成員att ributes,你應該去抽象的超類,只做myFunction()抽象。否則,請使用通用接口,該接口僅定義兩個實現器(EasyGameplay和HardGameplay)將實現的方法簽名。