Animal
public abstract class Animal {
String name;
public Animal(String name) {
this.name = name;
}
}
Lion
public class Lion extends Animal {
public Lion(String name) {
super(name);
// TODO Auto-generated constructor stub
}
public void roar() {
System.out.println("Roar");
}
}
Deer
public class Deer extends Animal {
public Deer(String name) {
super(name);
}
public void runAway() {
System.out.println("Running...");
}
}
TestAnimals
public class TestAnimals {
public static void main(String[] args) {
Animal lion = new Lion("Geo");
Animal deer1 = new Deer("D1");
Animal deer2 = new Deer("D2");
List<Animal> li = new ArrayList<Animal>();
li.add(lion);
li.add(deer1);
li.add(deer2);
for (Animal a : li) {
if (a instanceof Lion) {
Lion l = (Lion) a;
l.roar();
}
if (a instanceof Deer) {
Deer l = (Deer) a;
l.runAway();
}
}
}
}
Is there a better way to iterate through the list without having to cast ?In the above case it seem's ok but if you have many extensions of the base class then we'll need that many if block too.Is there a design pattern or principle to address this problem ?
The isInstance method is equivalent to instanceof operator. The method is used in case of objects are created at runtime using reflection. General practice says if the type is to be checked at runtime then use the isInstance method otherwise instanceof operator can be used.
Probably most of you have already heard that using “instanceof” is a code smell and it is considered as a bad practice. While there is nothing wrong in it and may be required at certain times, but the good design would avoid having to use this keyword.
Using the instanceof Operator When an Object Is nullIf we use the instanceof operator on any object that's null, it returns false. We also don't need a null check when using an instanceof operator.
A nested if statement is an if-else statement with another if statement as the if body or the else body. Here's an example: if ( num > 0 ) // Outer if if ( num < 10 ) // Inner if System. out.
An elegant way of avoiding instanceof
without inventing some new artificial method in the base class (with a non-descriptive name such as performAction
or doWhatYouAreSupposedToDo
) is to use the visitor pattern. Here is an example:
Animal
import java.util.*;
abstract class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public abstract void accept(AnimalVisitor av); // <-- Open up for visitors.
}
Lion and Deer
class Lion extends Animal {
public Lion(String name) {
super(name);
}
public void roar() {
System.out.println("Roar");
}
public void accept(AnimalVisitor av) {
av.visit(this); // <-- Accept and call visit.
}
}
class Deer extends Animal {
public Deer(String name) {
super(name);
}
public void runAway() {
System.out.println("Running...");
}
public void accept(AnimalVisitor av) {
av.visit(this); // <-- Accept and call visit.
}
}
Visitor
interface AnimalVisitor {
void visit(Lion l);
void visit(Deer d);
}
class ActionVisitor implements AnimalVisitor {
public void visit(Deer d) {
d.runAway();
}
public void visit(Lion l) {
l.roar();
}
}
TestAnimals
public class TestAnimals {
public static void main(String[] args) {
Animal lion = new Lion("Geo");
Animal deer1 = new Deer("D1");
Animal deer2 = new Deer("D2");
List<Animal> li = new ArrayList<Animal>();
li.add(lion);
li.add(deer1);
li.add(deer2);
for (Animal a : li)
a.accept(new ActionVisitor()); // <-- Accept / visit.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With