我有一些关于向上/向下的问题。
我创建了一个抽象父类(super class) Animal、子类 Dog 和子类 BigDog。我还在 Animal 中给出了抽象方法,并在 Dog 和 BigDog 中重写了它。
abstract public class Animal {
abstract public void greeting();
}
public class Dog extends Animal {
@Override
public void greeting() {
System.out.println("Woof!");
}
}
public class BigDog extends Dog {
@Override
public void greeting() {
System.out.println("Woow!");
}
}
现在是我的测试代码:
public class TestAnimal {
public static void main(String[] args) {
Animal animal2 = new Dog();
Animal animal3 = new BigDog();
// Downcast
Dog dog2 = (Dog) animal2; //cast Animal class to Dog class, legit
BigDog bigDog2 = (BigDog) animal3; //cast Animal to BigDog, legit;
Dog dog3 = (Dog) animal3; //Animal Class contains BigDog cast into Dog?
dog2.greeting();
dog3.greeting(); //in which class the method is called?
}
}
我了解父类(super class)/子类之间的关系以及强制转换的工作原理。然而,我的问题是,您是否可以将父类(super class)转换为特定的子类,并且知道中间有一个类?例如,如果我有一个 Animal 类对象包含一个 BigDog 对象,我可以将该对象强制转换为 Dog 吗?如果 BigDog 中有 Dog 中不存在的方法怎么办?
简而言之,你当然可以说父类(super class)对象是子类对象,但为什么可以颠倒呢?
转念一想,
我猜测是这样的:我要求 JVM 将 Animal 类引用转换为 Dog 并将新的 Dog 引用链接到 BigDog 对象,而不是真正转换 BigDog 对象。
因此,我可以调用该 Dog 引用(对 BigDog)的所有 Dog 和 Animal 方法,但不能调用任何 BigDog 方法,除非它在 BigDog 中被重写。
Java在调用方法时检查的是:引用(DOG)是否具有引用,以及对象(BigDog)是否具有覆盖。如果没有,则调用 Dog 方法,否则,调用 BigDog 方法。
谁能证实我的猜测吗?
最佳答案
您始终可以转换为特定的子类,除非编译器足够聪明,可以确定您的转换是不可能的。
转换为子类的最佳方法是检查是否可以完成:
if ( doggy instanceof BigDog ) {
doSomethingWithBigdog( (BigDog) doggy );
} else if ( doggy instanceof SmallDog ) {
doSomethingWithSmalldog( (SmallDog) doggy );
} else {
// Neither a big dog nor a small dog
}
...
private void doSomethingWithBigdog( BigDog dog ) {
...
}
private void doSomethingWithSmalldog( SmallDog dog ) {
...
}
请记住,选角是邪恶的。有时是必要的,但通常(并非总是)它可以通过在基类上实现方法来设计,或者通过不将 Dog 分配给 Animal 变量但保持其为 Dog 来设计。
关于java - 将子类对象转换为父类(super class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18530321/