Reputation:
Well, this is kind of embarrassing, but I've forgotten how to do the following in plain old Java:
abstract class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}
class Flea extends Animal {
private double jumpHeight;
public Flea(String name, double jumpHeight) {
super(name);
this.jumpHeight = jumpHeight;
}
public double jump() {
return jumpHeight();
}
}
class Giraffe extends Animal {
private int strideLength;
public Giraffe(int strideLength) {
super("Berta");
this.strideLength = strideLength;
}
public int stride() { return strideLength; }
}
class Gorilla extends Animal {
private String call;
public Gorilla(String call) {
super("Boris");
this.call = call;
}
public String call() { return "Gorilla says " + call; }
}
Now I would like to decide the appropriate method at runtime, without having to add all the methods to each Animal (no abstract methods) and without meaningless placeholders (like imagine a Flea has no call).
I would like to do this without casting. So no:
if(Animal instanceof Gorilla) ((Gorilla) animal).call();
I could come up with a solution incorporating interfaces like jumpable
and could use that, but I'm sure there was a certain pattern that was exactly for this kind of task.
Any ideas?
Upvotes: 0
Views: 86
Reputation: 3367
You should consider the visitor pattern:
abstract class Animal {
public abstract void acceptAnimalVisitor(AnimalVisitor visitor);
}
class Flea extends Animal {
public void acceptAnimalVisitor(AnimalVisitor visitor){
visitor.visit(this);
}
}
// other animals also implementing acceptAnimalVisitor
public class AnimalVisitor{
public void visit(Flea flea){
// ...
}
// other visit methods for the other animals
}
However, this requires at least one method (the accept method itself). Also note that you can convert the AnimalVisitor into an interface, and that way you can easily achieve the so called double dispatch.
Upvotes: 2