简体   繁体   English

具有类对象的Java泛型

[英]Java Generics With Class Object

I have three classes Dog.java , Cat.java and Monkey.java all implementing interface Animal.java . 我有三个类Dog.javaCat.javaMonkey.java都实现了Animal.java接口。 I then have DogManager.java , CatManager.java and MonkeyManager.java each having the following method and returning a Dog, Cat, Monkey instance respectively: 然后,我拥有DogManager.javaCatManager.javaMonkeyManager.java它们分别具有以下方法并分别返回Dog,Cat,Monkey实例:

public Animal getAnimal(); 

Finally I have a factory class that takes an animal name and returns an appropriate animal instance. 最后,我有一个采用动物名称并返回适当的动物实例的工厂类。

public Animal getAnimal(String name);

This all works fine, till I have to use the Animal object returned by the factory class to my controller class where I expect to call the bark() method exposed by Dog.java when I get the Dog instance from the factory but I don't have that method available since my factory returns Animal type which does not have bark() . 一切正常,直到我必须使用工厂类返回给控制器类的Animal对象,在我从工厂获得Dog实例时,我希望调用Dog.java公开的bark()方法,但我不这样做。因为我的工厂返回没有bark()动物类型,所以没有可用的方法。

So I was thinking of trying passing a class object to the getAnimal() in my factory class: 所以我想尝试将类对象传递给工厂类中的getAnimal():

public <T> T getAnimal(String name, Class<T implements Animal> clazz);    

However, this requires I know the class association for each animal name. 但是,这需要我知道每种动物名称的类别关联。 I was trying the following: 我正在尝试以下方法:

IManager.java IManager.java

Class<?> getClassName();
String getName();

DogManager.java DogManager.java

public Class<?> getClassName(){
    return Dog.class;
}

public String getName(){
    return "Dog";
}

public Dog getName(){
    return new Dog();
}

CatManager.java CatManager.java

Class<?> getClassName(){
    return Cat.class;
}

public String getName(){
    return "Cat";
}

And then in my factory call: 然后在我的工厂电话中:

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

But this does not work, since getAnimal takes Class and manager.getClassName() is returning Class. 但这是行不通的,因为getAnimal采用Class,而manager.getClassName()返回Class。

Any idea how can I make this work? 你知道我该怎么做吗?

Once you have an Animal instance and you know that it is a Dog, you can cast it as a Dog and use all the methods of the Dog class. 一旦有了Animal实例并且知道它是Dog,就可以将其强制转换为Dog并使用Dog类的所有方法。

Let´s see an example: 让我们看一个例子:

Dog dog = new Dog();
Animal animal = dog;

Right now, you can not use the bark() method directly in the animal instance (animal.bark() is not possible). 现在,您不能直接在动物实例中使用bark()方法(不可能使用animal.bark())。

But if you use casting '(Dog) animal', you will have all the Dog methods available for the object casted. 但是,如果您使用投射“(狗)动物”,则将具有所有可用于投射对象的Dog方法。

if(animal instanceof Dog){
    ((Dog) animal).bark();
}

The way to solve this is to add in your method signature the Class of the Animal you want to get, as the compiler can't guess the Animal you want to get when you're coding factory.getAnimal(name, manager.getClassName()) . 解决此问题的方法是在方法签名中添加要获取的Animal的类,因为编译器无法在编码factory.getAnimal(name, manager.getClassName())

So the answer is to add a parameterized Type to your IManager so the getAnimal() method returns the good type. 因此,答案是向IManager添加参数化的Type,以便getAnimal()方法返回良好的type。 But even if you do this, you will have to cast an Animal in the subtype you are looking for as the getAnimal() method can only return an Animal without getting any compilation error. 但是即使这样做,也必须在要查找的子类型中getAnimal() Animal ,因为getAnimal()方法只能返回Animal而不会出现任何编译错误。

You won't be able to have any Dog or Cat unless, somewhere, you don't write it down in your code 除非在某个地方没有将其写下来,否则您将无法拥有任何DogCat

This is a great example of a terrible technique. 这是可怕技术的一个很好的例子。 Consider saving it as a cautionary tale of "bad things people do". 考虑将其保存为“人们做坏事”的警示。 If you truly wish to continue walking this path to fiasco, then consider the following: 如果您确实希望继续走这条惨败之路,请考虑以下事项:

  1. None of this will be an example of good or quality software development. 这些都不是优质或高质量软件开发的示例。
  2. Add methods like "Dog getDog()" to the Animal interface. 将诸如“ Dog getDog()”之类的方法添加到Animal接口。 If the implementation is a Dog, this method will return the Animal cast to a Dog, if not, it will return null. 如果实现是Dog,则此方法会将Animal强制转换为Dog,否则,将返回null。 Maybe add "boolean isDog()" as well. 也许还要添加“ boolean isDog()”。
  3. In the Dog class, implement the isDog as something like this: return true; 在Dog类中,将isDog实现为如下所示: return true; .
  4. In the Cat class, implement the isDog method like this: return false . 在Cat类中,像这样实现isDog方法: return false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM