我有三个课程Dog.java
,Cat.java
和Monkey.java
都在实施接口Animal.java
。然后我DogManager.java
,CatManager.java
和MonkeyManager.java
分别使用以下方法并分别返回Dog,Cat,Monkey实例:
public Animal getAnimal();
最后,我有一个工厂类,它接受一个动物名称并返回一个合适的动物实例。
public Animal getAnimal(String name);
这一切都运行正常,直到我必须使用工厂类返回的Animal
对象到我的控制器类,我希望在我得到的时候调用Dog.java公开的bark()
方法来自工厂的狗实例,但我没有提供该方法,因为我的工厂返回了没有bark()
的动物类型。
所以我在尝试将类对象传递给工厂类中的getAnimal():
public <T> T getAnimal(String name, Class<T implements Animal> clazz);
但是,这需要我知道每个动物名称的类关联。我正在尝试以下方法:
IManager.java
Class<?> getClassName();
String getName();
DogManager.java
public Class<?> getClassName(){
return Dog.class;
}
public String getName(){
return "Dog";
}
public Dog getName(){
return new Dog();
}
CatManager.java
Class<?> getClassName(){
return Cat.class;
}
public String getName(){
return "Cat";
}
然后在我的工厂电话中:
IManager manager = getManager(); //Here I will get one of the Cat/Dog/Monkey managers based on name
factory.getAnimal(name, manager.getClassName()); //Compilation fails here
但这不起作用,因为getAnimal接受Class而manager.getClassName()返回Class。
我知道如何才能使这项工作?
答案 0 :(得分:2)
一旦你有了一个Animal实例并且你知道它是一个Dog,你就可以将它作为Dog进行投射并使用Dog类的所有方法。
让我们看一个例子:
Dog dog = new Dog();
Animal animal = dog;
现在,你不能直接在动物实例中使用bark()方法(不可能使用animal.bark())。
但是如果你使用铸造'(狗)动物',你将拥有可用于铸造物体的所有Dog方法。
if(animal instanceof Dog){
((Dog) animal).bark();
}
答案 1 :(得分:0)
解决这个问题的方法是在您的方法签名中添加您想要获得的动物类,因为编译器无法猜测您在编码时想要获得的动物{{1 }}
所以答案是将参数化类型添加到factory.getAnimal(name, manager.getClassName())
,以便IManager
方法返回良好类型。但即使你这样做,你也必须在你要查找的子类型中强制转换getAnimal()
,因为Animal
方法只能返回getAnimal()
而不会出现任何编译错误。
您无法拥有任何Animal
或Dog
,除非在某个地方您没有在代码中将其写下来
答案 2 :(得分:0)
这是一个可怕技术的一个很好的例子。 考虑将其保存为人们做的坏事#34; 如果你真的希望继续走这条路去惨败,那么请考虑以下几点:
isDog
实现为:return true;
。isDog
方法,如下所示:return false
。