Reputation: 3611
I'm creating a game in Android Studio. The game has a Easy mode and a Hard mode (respectively hard=False
and hard=True
).
Both the Easy mode and the Hard mode have their own class. Both these classes contain the same functions, but their implementation differs. I'm calling the functions in these classes from my Gameplay class. This means that in every function in my Gameplay class, I have to do the following:
if (hard == True):
HardGameplay gameplayMode = new HardGameplay();
else:
EasyGameplay gameplayMode = new EasyGameplay();
functionResult = gameplayMode.myFunction();
However, instead of performing this if-else check in each function, I'd like to check this just once. Therefore, I have created a checkDifficulty() function, which I call at the start of my onCreate:
public ??? gameplayMode;
public Boolean easyOrHard() {
if (hard == True):
HardGameplay gameplayMode = new HardGameplay();
else:
EasyGameplay gameplayMode = new EasyGameplay();
}
The problem is, I don't know what type I should place at the ???
. It should be either HardGameplay
or EasyGameplay
, but I don't know which of these two in advance. Putting Object
there doesn't work either, because then, each function I call gives the error Cannot resolve method 'myFunction()'
.
Does anybody know what to do? Or maybe there's an easier implementation I'm overlooking? Any help is greatly appreciated!
Upvotes: 1
Views: 1802
Reputation: 831
You just have to use an interface :
public interface GamePlay {
... // Your different methods declaration
}
Your two classes will implement this interface :
public class HardGamePlay implements GamePlay {
... // You override the methods here
}
public class EasyGamePlay implements GamePlay {
... // You override the methods here
}
You can then use :
GamePlay gamePlayMode = easyOrHard();
public GamePlay easyOrHard() {
if (hard) {
return new HardGameplay();
} else {
return new EasyGameplay();
}
This is called Polymorphism
: http://www.artima.com/objectsandjava/webuscript/PolymorphismInterfaces1.html
Upvotes: 4
Reputation: 877
You need Polymorphism.
So create a superclass called GamePlay
and make HardGamePlay
and EasyGamePlay
extend these classes. This superclass defines the functions which will be implemented by its subclasses
public abstract class GamePlay {
public abstract void myFunction();
}
public class HardGamePlay extends GamePlay {
public void myFunction() {
//your code here
}
}
Then you can use
public GamePlay gamePlayMode
In your GameActivity do this:
Gameplay gameplay = null;
if (hardmode)
gameplay = new HardGamePlay();
else
gameplay = new EasyGamePlay();
Upvotes: 7
Reputation: 1164
Basically you got 2 answers so far above:
1) use abstract base class with abstract myFunction()
2) have a common interface with myFunction() that both EasyGameplay and HardGameplay implement
The way you decide between the two approaches is how much common implementation data and behavior is between the two: if at least one method implementation (not just method signature) can be shared and/or the classes have the same class member attributes, you should go with an abstract superclass and make only myFunction() abstract. Otherwise, use a common interface which defines only method signatures that the two implementors (EasyGameplay and HardGameplay) will implement.
Upvotes: 2
Reputation: 139
As Simon said, you can create a superclass that is being extended by HardGamePlay and EasyGamePlay. This would work if both classes have the same method nomenclature.
However, if the EasyGamePlay and the HardGamePlay classes have different methods you can try using Object, but keep in mind that you need to cast it to the appropriate class before calling the method.
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();
}
}
}
And still, the best way to go is to use polymorphism so you avoid using Object variables/fields. If you cannot use polymorphism consider reviewing your software architecture
Upvotes: 1
Reputation: 7357
If both classes would contain the same methods, you could simply create a Game
interface, which you could use as a variable type.
public interface Game {
void methodA();
void methodB();
}
Both modes could now implement from this interface
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
}
}
You could now create a variable Game
and assign the specific type of the mode to it. Due to both of them having a common interface you can still acces both classes the same way, as it can be seen in the method 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();
}
}
Upvotes: 3