我对上/下流有一些疑问。
我创建了一个抽象的超类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?
}
}
我了解超类/子类与强制转换的工作方式之间的关系。我的问题是,但是,您可以在知道两者之间存在一个类的情况下,将超类转换为特定的子类吗?例如,如果我有一个Animal类对象包含BigDog对象,我可以将该对象转换为Dog吗?如果BigDog中的某些方法在Dog中不存在,该怎么办?
简而言之,您可以肯定地说超类对象是子类对象,但是为什么要反转呢?
再三考虑
我正在猜测:我是在问JVM将Animal类引用转换为Dog并将新的Dog引用链接到BigDog对象,而不是真正地转换BigDog对象。
因此,我可以在该Dog引用(指向BigDog)上调用所有Dog和Animal方法,但不能调用BigDog方法,除非在BigDog中对其进行了覆盖。
Java在调用方法时检查的是:引用(DOG)是否具有引用,以及对象(BigDog)是否具有覆盖。如果不是,则调用Dog方法,否则,调用BigDog方法。
谁能证实我的猜测?
方法的正确用法:dog2.greeting();和dog3.greeting();或添加方法public void greeting(Animal animal);。 然后将编译源代码。
抱歉,大家复制并粘贴,忘记更改参数。
对于变量的静态类型还是动态类型,这是一个很好的示例。 有几本书/线程
您始终可以将其强制转换为特定的子类,除非编译器足够聪明,可以肯定地知道您的强制转换是不可能的。
转换为子类的最佳方法是检查是否可以完成:
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。
首先纠正源代码,以便将其编译。方法的正确用法:dog2.greeting();和dog3.greeting();或添加方法public void greeting(Animal animal);。
dog3.greeting();-为dog3调用方法greeting()。 dog3与animal3具有相同的引用。 animal3引用了BigDog,因此对类BigDog调用了方法greeting(),输出为Woow!
从类Animal继承Dog时,类Dog具有类Animal的所有方法。
If I have an Animal class object contains a BigDog object, can I cast the object to Dog? what if there are methods in BigDog that do not exist in Dog?。
简单地说,您将获得编译器错误。由于您无法使用父引用调用未在父类中声明且在子类中声明的方法
没有方法的签名与这些方法调用相匹配:
dog2.greeting(dog3);
dog3.greeting(dog2);
因此,它几乎是编译失败。
您需要了解动态方法调度。
这是通过它们的几个链接1,2,3。
复制和粘贴时出现我的错误。 原始代码必须具有to方法。
好。 浏览答案中的链接。 狗引用所引用的对象都会调用greeting()。