繁体   English   中英

如何避免Java中的instanceof检查

[英]How to avoid instanceof check in Java

我具有以下类结构:

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子类的检查实例吗? 有什么办法可以做到这一点? 如何使用访问者模式替换它?

Thing是基类。 Pet是一个抽象类,具有方法eat() Tiger子类需要eat方法的特定实现。

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

我可以想到几种解决方案:

  1. 将支票移至Thing: if (thing.isEatable())
  2. 如果无法食用,让事物抛出异常: try { eat(thing); } catch … try { eat(thing); } catch …
  3. 不要以为所有宠物都能吃东西。 从宠物中删除eat(Thing)方法,并在Tiger添加eat(Creature)eat(Food)方法。
  4. 将逻辑移到Thing 调用thing.beingEaten() ,并在Creature重写该方法以调用doSomething而不是eat

编辑:

仅当事物是Creature如何调用doOneThing()

使用instanceof:

class Tiger extends Pet {
    void eat (Thing thing) {
        if (thing is instanceOf Creature) {
            doOneThing();
        } else {
            doOtherThing();
        }
    }
}

没有instanceof:

class Tiger extends Pet {
    void eat(Thing thing) {
        thing.beEaten();
    }
}

class Creature extends Thing {
    void beEaten() {
        doOneThing();
    }
}

class Thing {
    void beEaten() {
        doOtherThing();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM