首先我要说我试着在谷歌搜索这个问题的答案,但没有答案解释了我的怀疑。无论如何,我想要了解的是以下内容:
public interface Animal{
public void makeSound(int times);
}
该接口有两种不同的实现:
public class Cat implements Animal{
@Override
public void makeSound(int times){
for(int=0;i<times;i++){
this.meow();
}
}
}
public class Dog implements Animal{
@Override
public void makeSound(int times){
for(int=0;i<times;i++){
this.wolf();
}
}
}
我将使用这些实现,如以下示例所示:
public class AnimalStateManager {
@Inject
private Animal animal;
public void makeAnimalAct(){
animal.makeSound(100)
}
}
更新1.1到帖子
我还有一个类使用相同的“Animal”界面:
public class AnimalMakeSoundOnce {
@Inject
private Animal animal;
public void makeSoundOnce(){
animal.makeSound(1)
}
}
所以我的问题是:1-我怎么知道将什么实现注入AnimalStateManager? 2-如果我想强制“AnimalStateManager”上的“动物”对象成为猫,该怎么办?
更新1.1到POST 3-如果我想让AnimalMakeSoundOnce使用Dog实现并且AnimalStateManager使用Cat实现怎么办?
提前致谢
在Guice中,您必须实现一个模块(覆盖AbstractModule
类)并将Animal绑定到特定的实现类。回答你的问题:
animal.getClass()
在运行时检查注入了哪个实现类。但是这会破坏IOC的原则,在这里您使用哪种具体实现无关紧要。animal
中的AnimalStateManager
是cat,你必须编写自己的模块。
public class AnimalStateModule extends AbstractModule {
@Override
protected void configure() {
bind(Animal.class).to(Cat.class);
}
}
并实例化AnimalState:
Injector inj = Guice.createInjector(new AnimalStateModule());
final AnimalStateManager ass = inj.getInstance(AnimalStateManager.class);
ass.makeAnimalAct(); // will cause a call to Cat.meow()
我认为另一个重要的问题是你将如何使用MakeSound和MakeSoundOnce对象。在上面创建的同一模块中,有许多方法可以指定所需的类型,这两种方法都是绑定所述注释的方法(https://github.com/google/guice/wiki/BindingAnnotations):
1)您可以使用Guice提供的@Named注释。你有一些看起来如下的东西:
@Override
protected void configure() {
bind(Animal.class).annotatedWith(Names.named("Cat")).to(Cat.class);
bind(Animal.class).annotatedWith(Names.named("Dog")).to(Dog.class);
}
然后将用于:
@Inject @Named("Cat") private Animal animal;
在你的* MakeSound课程中。
2)您还可以创建自己的注释(在上面相同的链接中描述,具有非常好的细节),这将为您提供使用选项:
@Inject @Cat private Animal animal;
在你的* MakeSound课程中。大多数情况下,我们坚持使用@Named注释,因为它不需要创建额外的Annotation接口。
* MakeSound类是否会通过Injection实现?你是否需要在你所描述的* MakeSound类中切换Dog / Cat实现(即想让猫只喵一次,反之亦然)?