是否可以在 Java 中使用依赖注入在运行时对接口对象进行类型转换?

问题描述 投票:0回答:1
public interface Animal {
    void speak();
}

public class Dog implements Animal{
    void speak (){
        System.out.println("This is dog.")
    }
}

public class Cat implements Animal{
    void speak (){
        System.out.println("This is cat.")
    }
}


@Module
public class Module{

    @Provides
    @Named("Dog")
        static Animal providesDog() {
            return new Dog();
    }

    @Provides
    @Named("Cat")
        static Animal providesCat() {
            return new Cat();
        }
}

public class AnimalOrchestrator {

    @Inject
    Animal animal;

    public void speak(String type) {

        if(type.equals("dog")
            (Dog) animal.speak();
        else
            (Cat) animal.speak();

    }
}

在运行时我们确定 Animal 对象应该转换为哪个 Dog/Cat 对象时,这种类型转换是否可能?

以下是实现此类功能的其他一些方法。

public class AnimalOrchestrator {

    @Inject
    Dog dog;

    @Inject
    Cat cat;

    public void speak(String type) {

        if(type.equals("dog")
            dog.speak();
        else
            cat.speak();

    }
}

上面的代码有一个缺点,我们需要创建狗和猫的对象,尽管只会使用上面的其中之一。

另一种方法如下:

public class AnimalOrchestrator {

    Animal animal;

    public void speak(String type) {

        if(type.equals("dog"){
            animal = new Dog();
            animal.speak();
        } else {
            animal = new Cat();
            animal.speak();
        }
    }
}

有了这个,我们必须使用我想避免的 new 运算符创建这个对象,以便利用依赖注入。

第一个解决方案可能吗?如果是的话,哪个更好?

java oop interface casting dagger
1个回答
0
投票

在回答这个问题之前,我应该注意到我没有使用@Inject Annotation,但我认为代码可以与它一起使用。

现在您要求的是复合模式。

使用类型变量来确定哪种动物是猫还是狗违反了开闭原则。您的代码可供修改。将来每当您需要新动物时,您都将添加新的类型检查代码。这意味着您的 AnimalOrchestrator 会发生很多变化,并且可能会导致很多错误。

现在答案是这样的;

public interface Animal {
    void speak();
}

public class Cat implements Animal {

    @Override
    public void speak() {
        System.out.println("This is Cat");
    }

}

public class Dog implements Animal {

    @Override
    public void speak() {
        System.out.println("This is Dog");
    }

}

public class Mammals implements Animal {

    private List<Animal> animalList;
    
    public Mammals(Animal... animals){
        this.animalList = Arrays.asList(animals);
    }
    
    @Override
    public void speak() {
        for(Animal animal : this.animalList){
            animal.speak();
        }
        
        System.out.println("This is Mammals");
    }

}

请注意,您的 AnimalOrchestrator 类将以这种方式成为我的 Mammals 类

© www.soinside.com 2019 - 2024. All rights reserved.