首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类设计-手动强制转换替代方案

类设计-手动强制转换替代方案
EN

Stack Overflow用户
提问于 2018-02-28 17:07:32
回答 2查看 84关注 0票数 1

问题与下面的类相关。Zookeeper1和Zookeeper2是我可以使用的两个替代方案。我可以在未来在Zookeeper中存储不同类型的动物。我应该能够得到这些类。在第一种情况下,我将所有的动物存储在列表中(这意味着将来我可以很容易地添加其他新的动物),但当我需要获得它时,我需要使用( dog )来投掷狗。在某个地方读到强制转换是代码嗅觉,所以我想看看有没有其他选择?其他解决方案会阻止强制转换,但每次我添加新动物时都会出现添加新列表的问题。

代码语言:javascript
复制
class AnimalId{}

interface Animal{
    AnimalId getAnimalId();
    void breathe();
}

class Cat implements Animal{
    public AnimalId getAnimalId() { return null; }
    public void breathe() {}
}

class Dog implements Animal{
    public AnimalId getAnimalId() { return null; }
    public void breathe() {}
    public void bark(){}
}

class ZooKeeper1{
    Map<AnimalId, Animal> animals = new HashMap<>();    //future-proof

    void addAnimal(Animal a){
        animals.put(a.getAnimalId(), a);
    }

    void printAnimals(){
        animals.forEach((key, value) -> System.out.println(key));
    }

    Dog getDog(AnimalId animalId){
        return (Dog)animals.get(animalId);  //NOK - must type-cast!
    }

    public static void main(String[] args) {
        ZooKeeper1 zk1 = new ZooKeeper1();
        zk1.addAnimal(new Cat());
        zk1.addAnimal(new Dog());
        zk1.printAnimals();
        Dog d = zk1.getDog(new AnimalId());
        d.bark();
    }
}

class ZooKeeper2{
    Map<AnimalId, Cat> cats = new HashMap<>();
    Map<AnimalId, Dog> dogs = new HashMap<>();  //will need to add more lines in future

    void addCat(Cat c){
        cats.put(c.getAnimalId(), c);
    }

    void addDog(Dog d){
        dogs.put(d.getAnimalId(), d); //will need to add more lines in future
    }

    void printAnimals(){
        cats.forEach((key, value) -> System.out.println(key));
        dogs.forEach((key, value) -> System.out.println(key)); //will need to add more lines in future
    }

    Dog getDog(AnimalId animalId){
        return dogs.get(animalId);  //OK no type-cast
    }

    public static void main(String[] args) {
        ZooKeeper2 zk2 = new ZooKeeper2();
        zk2.addCat(new Cat());
        zk2.addDog(new Dog());
        zk2.printAnimals();
        Dog d = zk2.getDog(new AnimalId());
        d.bark();
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-12 20:40:02

好的,那么在研究了Java中的异构容器之后,我想这将是到目前为止我有的最好的选择?对这类解决方案有什么意见吗?

代码语言:javascript
复制
interface Animal { AnimalId getId(); }
class AnimalId { int id; AnimalId(int id){this.id = id;} public boolean equals(Object o){ return id==((AnimalId)o).id; } public int hashCode(){ return 1; } }
class Cat implements Animal { AnimalId id; Cat(AnimalId id){this.id=id;} public AnimalId getId(){ return id; } public String catSpecific(){ return "CS"; } }
class Dog implements Animal { AnimalId id; Dog(AnimalId id){this.id=id;} public AnimalId getId(){ return id; } public String dogSpecific(){ return "DS"; } }

class Zoo {
    private Map<Class<? extends Animal>, Map<AnimalId, Animal>> animals = new HashMap<>();

    public <T extends Animal> void assignAnimal(T animal){
        animals.computeIfAbsent(animal.getClass(), k -> new HashMap<>()).put(animal.getId(), animal);
    }

    public <T extends Animal> T getAnimal(Class<T> type, AnimalId animalId){
        return type.cast(animals.get(type).get(animalId));
    }

    public static void main(String[] args) {
        Zoo zoo = new Zoo();

        AnimalId animalId = new AnimalId(1);
        Animal animal1 = new Cat(animalId);
        Animal animal2 = new Dog(animalId);

        zoo.assignAnimal(animal1);
        zoo.assignAnimal(animal2);

        Cat cat = zoo.getAnimal(Cat.class, animalId);
        Dog dog = zoo.getAnimal(Dog.class, animalId);

        System.out.println(cat.catSpecific());
        System.out.println(dog.dogSpecific());
    }
}
票数 0
EN

Stack Overflow用户

发布于 2018-03-02 05:09:22

想象一下,我在不了解Dog类的情况下编写了ZooKeeper1类,并将其传递给了您。然后,您决定扩展该类并添加方法Dog getDog(AnimalId id)

你希望这能正常工作吗?如果你看到了推理中的差距,那么你就明白为什么选角是个坏主意了。

铸造并不是一个神奇的解决方案。使用它的唯一安全方法是仅强制转换已知类型的对象;例如,如果将Dog实例存储在类型为Animal的变量中,则可以肯定地将getAnimal(..)的结果强制转换为类型Dog

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49025685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档