gpt4 book ai didi

java - 如何避免大的 if 语句和 instanceof

转载 作者:太空狗 更新时间:2023-10-29 22:42:03 27 4
gpt4 key购买 nike

动物

public abstract class Animal {
String name;

public Animal(String name) {
this.name = name;
}

}

狮子

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...");
}

}

测试动物

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 block 。有没有设计解决这个问题的模式或原则?

最佳答案

一种避免 instanceof 的优雅方法,无需在基类中发明一些新的人工方法(使用非描述性名称,例如 performActiondoWhatYouAreSupposedToDo) 是使用visitor pattern 。这是一个例子:

动物

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.

}

狮子鹿

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();
}
}

测试动物

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.
}
}

关于java - 如何避免大的 if 语句和 instanceof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3930808/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com