[英]How to Down Cast an Object in Java
I am working with an API in my company where I would like to create a subclass for an existing object. 我正在使用我公司的API,我想为现有对象创建一个子类。 Here are the caveats:
以下是警告:
The example I see most commonly is a Dog as a subclass of Animal, so I will use that. 我最常见的例子是Dog作为Animal的子类,所以我将使用它。 Let's say you have this class in the API:
假设你在API中有这个类:
//API class, which I cannot modify
public class Animal(){
public void eat(){
//All animals can do this
}
}
Now I would like to create a class like this, which adds a few methods to Animal. 现在我想创建一个这样的类,它为Animal添加了一些方法。
//My subclass, which I can modify
public class Dog extends Animal(){
public void fetch(){
//Only dogs can do this
}
}
So now let's say I have an instance of Animal (one that is not a Dog). 所以现在让我说我有一个动物实例(一个不是狗)。 I essentially need to downcast it into a Dog.
我基本上需要把它变成一只狗。 I get that downcasting is not directly supported in Java, but is there any workaround for this?
我认为Java中没有直接支持这种向下转换,但有没有解决方法呢?
public class AnimalExample{
public static void main(String[] args){
Animal animal = MyApi.getAnAnimal();
//Dog dog = (Dog) animal; ---throws a runtime error
Dog dog = Dog.getDog(animal); //Maybe something like this?
//Then I should be able to call both eat() and fetch()
dog.eat();
dog.fetch();
}
}
Again, I understand that downcasting is not directly supported. 我再次理解,不直接支持向下转换。 But there has to be some workaround for this, and I can't figure it out.
但是必须有一些解决方法,我无法弄明白。 I know that I could use a wrapper class (eg
DogWrapper
), but that would be a little more difficult than I'd like because I still frequently call the dozens of superclass methods. 我知道我可以使用包装器类(例如
DogWrapper
),但这比我想要的要困难一些,因为我仍然经常调用几十种超类方法。
UPDATE : I understand that it's not yet a Dog, but I was wondering if there was a way to convert it into a Dog. 更新 :我知道它还不是狗,但我想知道是否有办法将它转换为狗。 It basically sounds like, from what people are saying, that I either have to convert it manually (copy each attribute/method over one-by-one) or just use a Wrapper class.
从人们的说法来看,它基本上听起来像我必须手动转换它(逐个复制每个属性/方法)或者只使用Wrapper类。 A Wrapper class seems a lot less messy, so unfortunately I'll just have to go that route.
一个Wrapper类似乎不那么混乱,所以不幸的是我只需要去那条路。 So
DogWrapper
will have a fetch()
method and a getAnimal()
method. 所以
DogWrapper
将有一个fetch()
方法和一个getAnimal()
方法。 So if I want the Dog
to eat, then I have to call dog.getAnimal().eat()
. 所以,如果我想让
Dog
吃,那么我必须叫dog.getAnimal().eat()
。 I was avoiding having to do that, but I guess there's no way around it. 我不必这样做,但我想没有办法解决它。 Does anyone see anything simpler than that?
有没有人看到比这更简单的东西?
You can have a constructor which takes Animal and instantiates the Dog part of the object with defaults or as required. 你可以有一个构造函数,它接受Animal并使用默认值或根据需要实例化对象的Dog部分。
public Dog (Animal animal) {
super(); // any instantiation that has to be done for animal
// Dog instantiation
// Use animal properties as required
}
Dog dog = new Dog(animal);
Also having a static method as you mentioned Dog.getDog(animal)
is an option, depends on your coding preference. 如上所述,还有一个静态方法
Dog.getDog(animal)
是一个选项,取决于你的编码偏好。
Let's suppose I create a method that requires a Dog
, but is meant to extend the Animal
API. 我们假设我创建了一个需要
Dog
的方法,但是它意味着扩展Animal
API。 Sure, I could just make the signature like so: 当然,我可以像这样签名:
public void doFetch(Dog dog)
But as I said, I want to extend the Animal
API. 但正如我所说,我想扩展
Animal
API。 Now, if the given Animal
is not a Dog
, I can't fetch. 现在,如果给定的
Animal
不是Dog
,我无法取。 With that in mind, I can do the following: 考虑到这一点,我可以做到以下几点:
public void doFetch(Animal fetcher) {
if(fetcher instanceof Dog) {
Dog dog = (Dog) fetcher;
... //Do fetchy things
return;
}
//If we reach this point, then the animal is not a dog
throw new IllegalArgumentException("fetcher is not a Dog!");
}
Now let's suppose, as in your case, I have an Animal
that is not a dog, but I want it to be a Dog
for some reason. 现在让我们假设,就像你的情况一样,我有一只不是狗的
Animal
,但出于某种原因我希望它成为一只Dog
。 In this case, I could convert any Animal
into a dog using some kind of translator. 在这种情况下,我可以使用某种翻译器将任何
Animal
转换为狗。 I prefer to define things like this as static
methods in the Dog
class itself: 我喜欢在
Dog
类本身中将这样的东西定义为static
方法:
//Breaks the laws of nature by making a Dog from any Animal.
public static Dog fromAnimal(Animal animal) {
Dog dog = new Dog();
//Here you would set all the properties of the animal, e.g.:
dog.setName(animal.getName());
...
return dog;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.