带有类对象的Java泛型

时间:2017-02-08 12:51:34

标签: java generics

我有三个课程Dog.javaCat.javaMonkey.java都在实施接口Animal.java。然后我DogManager.javaCatManager.javaMonkeyManager.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。

我知道如何才能使这项工作?

3 个答案:

答案 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()而不会出现任何编译错误。

您无法拥有任何AnimalDog,除非在某个地方您没有在代码中将其写下来

答案 2 :(得分:0)

这是一个可怕技术的一个很好的例子。 考虑将其保存为人们做的坏事#34; 如果你真的希望继续走这条路去惨败,那么请考虑以下几点:

  1. 这些都不是优质或高质量软件开发的典范。
  2. 添加&#34; Dog getDog()&#34;等方法。到Animal界面。如果实现是Dog,则此方法将Animal转换为Dog,如果不是,则返回null。也许添加&#34; boolean isDog()&#34;同样。
  3. 在Dog类中,将isDog实现为:return true;
  4. 在Cat类中,实现isDog方法,如下所示:return false