Animal
public abstract class Animal {
String name;
public Animal(String name) {
this.name = name;
}
}
Lion<
Here you have a List
of animals. Usually when you have a list of Objects, all these objects must be able to do the same thing without being casted.
So the best two solutions are :
abstract
in Animal
)Lion
from Deer
from the start, and have two different lists.Yes provide a method called action()
in abstract class , implement it in both of the child class, one will roar other will runaway
Consider adding an interface for the action (Roar, Run away, etc) which is set on the animal in the constructor. Then have an abstract method such as act() on the Animal class which gets called similar to what Adeel has.
This will let you swap in actions to act out via a field at any time.
If your method is not polymorphic you can't do without the cast. To make it polymorphic, declare a method in the base class and override it in the descendant classes.
The simplest approach is to have the super class implement a default behaviour.
public enum AnimalBehaviour {
Deer { public void runAway() { System.out.println("Running..."); } },
Lion { public void roar() { System.out.println("Roar"); } }
public void runAway() { }
public void roar() { }
}
public class Animal {
private final String name;
private final AnimalBehaviour behaviour;
public Animal(String name, AnimalBehaviour behaviour) {
this.name = name;
this.behaviour = behaviour;
}
public void runAway() { behaviour.runAway(); }
public void roar() { behaviour.roar(); }
}
public class TestAnimals {
public static void main(String... args) {
Animal[] animals = {
new Animal("Geo", AnimalBehaviour.Lion),
new Animal("Bambi", AnimalBehaviour.Deer),
new Animal("D2", AnimalBehaviour.Deer)
};
for (Animal a : animals) {
a.roar();
a.runAway();
}
}
}
Pattern matching support in the language eliminates the need for the ugly visitor pattern.
See this Scala code for example:
abstract class Animal(name: String)
class Lion(name: String) extends Animal(name) {
def roar() {
println("Roar!")
}
}
class Deer(name: String) extends Animal(name) {
def runAway() {
println("Running!")
}
}
object TestAnimals {
def main(args: Array[String]) {
val animals = List(new Lion("Geo"), new Deer("D1"), new Deer("D2"))
for(animal <- animals) animal match {
case l: Lion => l.roar()
case d: Deer => d.runAway()
case _ => ()
}
}
}