如何避免Java中的instanceof check
我的班级结构如下:如何避免Java中的instanceof check,java,instanceof,visitor-pattern,Java,Instanceof,Visitor Pattern,我的班级结构如下: class Thing { } abstract class Pet extends Thing { void eat(Thing thing) { // do something } } class Tiger extends Pet { void eat(Thing thing) { if (thing instanceOf Creature) // do Something
class Thing {
}
abstract class Pet extends Thing {
void eat(Thing thing) {
// do something
}
}
class Tiger extends Pet {
void eat(Thing thing) {
if (thing instanceOf Creature)
// do Something
else
super.eat(thing);
}
}
我想避免子类Tiger
中的check实例?有没有办法做到这一点?如何使用访问者模式替换此项
Thing
是一个基类。
Pet
是一个抽象类,它具有方法eat()
。
子类Tiger需要eat方法的具体实现。我可以想出几种解决方案:
if(Thing.isEatable())
尝试{eat(thing);}catch…
吃(东西)
方法,并将吃(生物)
或吃(食物)
方法添加到老虎
对象
。调用thing.beingEaten()
,并覆盖生物
中的该方法,以调用doSomething
而不是eat
生物时,如何调用doOneThing()
:
带有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
没有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
我可以想出几种解决办法:
将检查移动到Thing:if(Thing.isEatable())
如果不可吃,让thing抛出异常:尝试{eat(thing);}catch…
不要以为所有的宠物都能吃东西。从宠物中移除吃(东西)
方法,并将吃(生物)
或吃(食物)
方法添加到老虎
将逻辑移到对象
。调用thing.beingEaten()
,并覆盖生物
中的该方法,以调用doSomething
而不是eat
编辑:
只有当对象是生物时,如何调用doOneThing()
:
带有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
没有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
我可以想出几种解决办法:
将检查移动到Thing:if(Thing.isEatable())
如果不可吃,让thing抛出异常:尝试{eat(thing);}catch…
不要以为所有的宠物都能吃东西。从宠物中移除吃(东西)
方法,并将吃(生物)
或吃(食物)
方法添加到老虎
将逻辑移到对象
。调用thing.beingEaten()
,并覆盖生物
中的该方法,以调用doSomething
而不是eat
编辑:
只有当对象是生物时,如何调用doOneThing()
:
带有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
没有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
我可以想出几种解决办法:
将检查移动到Thing:if(Thing.isEatable())
如果不可吃,让thing抛出异常:尝试{eat(thing);}catch…
不要以为所有的宠物都能吃东西。从宠物中移除吃(东西)
方法,并将吃(生物)
或吃(食物)
方法添加到老虎
将逻辑移到对象
。调用thing.beingEaten()
,并覆盖生物
中的该方法,以调用doSomething
而不是eat
编辑:
只有当对象是生物时,如何调用doOneThing()
:
带有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
没有instanceof:
class Tiger extends Pet {
void eat (Thing thing) {
if (thing is instanceOf Creature) {
doOneThing();
} else {
doOtherThing();
}
}
}
class Tiger extends Pet {
void eat(Thing thing) {
thing.beEaten();
}
}
class Creature extends Thing {
void beEaten() {
doOneThing();
}
}
class Thing {
void beEaten() {
doOtherThing();
}
}
使用Map
尝试此解决方案:
import java.util.Map;
import java.util.HashMap;
interface ToDo {
void exec();
}
abstract class Animal {}
class Tiger extends Animal {}
class Dog extends Animal {}
class Ideone {
public static void main(String[] args) {
Map <Class, ToDo> map = new HashMap <Class, ToDo>();
map.put(Tiger.class, new ToDo() {
public void exec() {
System.out.println("do for tiger ...");
}
});
map.put(Dog.class, new ToDo() {
public void exec() {
System.out.println("do for dog ...");
}
});
for(Animal a : new Animal[]{new Tiger(), new Dog(), null}) {
try {
map.get(a.getClass()).exec();
} catch (NullPointerException npe) {
System.out.println("nothing to do ...");
}
}
}
}
import java.util.Map;
导入java.util.HashMap;
接口待办事项{
void exec();
}
抽象类动物{}
类{}
类狗扩展动物{}
表意文字{
公共静态void main(字符串[]args){
Map Map=newhashmap();
map.put(Tiger.class,new ToDo()){
public void exec(){
System.out.println(“为老虎做…”);
}
});
map.put(Dog.class,new ToDo()){
public void exec(){
System.out.println(“为狗做…”);
}
});
对于(动物a:新动物[]{new Tiger(),new Dog(),null}){
试一试{
get(a.getClass()).exec();
}捕获(NullPointerException npe){
System.out.println(“无事可做…”);
}
}
}
}
使用Map
尝试此解决方案:
import java.util.Map;
import java.util.HashMap;
interface ToDo {
void exec();
}
abstract class Animal {}
class Tiger extends Animal {}
class Dog extends Animal {}
class Ideone {
public static void main(String[] args) {
Map <Class, ToDo> map = new HashMap <Class, ToDo>();
map.put(Tiger.class, new ToDo() {
public void exec() {
System.out.println("do for tiger ...");
}
});
map.put(Dog.class, new ToDo() {
public void exec() {
System.out.println("do for dog ...");
}
});
for(Animal a : new Animal[]{new Tiger(), new Dog(), null}) {
try {
map.get(a.getClass()).exec();
} catch (NullPointerException npe) {
System.out.println("nothing to do ...");
}
}
}
}
import java.util.Map;
导入java.util.HashMap;
接口待办事项{
void exec();
}
抽象类动物{}
类{}
类狗扩展动物{}
表意文字{
公共静态void main(字符串[]args){
Map Map=newhashmap();
map.put(Tiger.class,new ToDo()){
public void exec(){
System.out.println(“为老虎做…”);
}
});
map.put(Dog.class,new ToDo()){
public void exec(){
System.out.println(“为狗做…”);
}
});
对于(动物a:新动物[]{new Tiger(),new Dog(),null}){
试一试{
get(a.getClass()).exec();
}捕获(NullPointerException npe){
System.out.println(“无事可做…”);
}
}
}
}
使用Map
尝试此解决方案:
import java.util.Map;
import java.util.HashMap;
interface ToDo {
void exec();
}
abstract class Animal {}
class Tiger extends Animal {}
class Dog extends Animal {}
class Ideone {
public static void main(String[] args) {
Map <Class, ToDo> map = new HashMap <Class, ToDo>();
map.put(Tiger.class, new ToDo() {
public void exec() {
System.out.println("do for tiger ...");
}
});
map.put(Dog.class, new ToDo() {
public void exec() {
System.out.println("do for dog ...");
}
});
for(Animal a : new Animal[]{new Tiger(), new Dog(), null}) {
try {
map.get(a.getClass()).exec();
} catch (NullPointerException npe) {
System.out.println("nothing to do ...");
}
}
}
}
import java.util.Map;
导入java.util.HashMap;
接口待办事项{
void exec();
}
抽象类动物{}
类{}
类狗扩展动物{}
表意文字{
公共静态void main(字符串[]args){
Map Map=newhashmap();
map.put(Tiger.class,new ToDo()){
public void exec(){
System.out.println(“为老虎做…”);
}
});
map.put(Dog.class,new ToDo()){
public void exec(){
System.out.println(“为狗做…”);
}
});
对于(动物a:新动物[]{new Tiger(),new Dog(),null}){
试一试{
get(a.getClass()).exec();
}捕获(NullPointerExcepti)