问题描述
动物
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");
}
}
鹿
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();
}
}
}
}
有没有更好的方法来迭代通过列表,而不必转换?在上面的情况下,似乎确定,但如果你有很多基类的扩展,那么我们将需要那么多if块。模式或原则来解决这个问题?
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 ?
推荐答案
避免 instanceof
没有在基类中创建一些新的人工方法(具有非描述性名称,例如 performAction
或 doWhatYouAreSupposedToDo
)是使用 。以下是一个示例:
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:
动物
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.
}
狮子 Deer
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.
}
}
访问者
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 >
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语句和instanceof的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!