以下是示例代码
class Animal {
void makeNoise() {System.out.println("generic noise"); }
}
class Dog extends Animal {
void makeNoise() {System.out.println("bark"); }
void playDead() { System.out.println("roll over"); }
}
class DogTest {
public static void main(String [] args) {
Animal animal = new Animal();
Dog d = (Dog) animal;
d.makeNoise();
}
}
上面的代码汇编得很好但是当我尝试运行它时,我得到了
java.lang.ClassCastException
我的假设是它应该打印"通用噪音"因为在运行时它应该调用实际的Animal对象makeNoise()方法而不给出任何异常。
答案 0 :(得分:4)
您不能将Animal
实例强制转换为Dog
实例,除非您投射的实例实际上是Dog
或{{1}的子类}}
Dog
类更抽象是抽象的,因为可以实例化的实际动物应该是特定的动物,例如Animal
,Dog
等。 ..
答案 1 :(得分:3)
如果你有:
Animal animal = new Dog();
Dog dog = (Dog) animal;
没有问题。
您需要了解编译时类型和运行时类型之间的区别。在上面的代码片段中,animal
的编译时间是Animal
,而运行时类型是Dog
。这就是 cast 到Dog
没有问题的原因(注意实际的转换是在运行时发生的)。
但是,在您的代码中,animal
的运行时类型为Animal
(与编译时类型相同)。这意味着animal
将指向堆上的对象,该对象支持Animal
(makeNoise()
)的功能,但不支持Dog
的功能这就是ClassCastException
发生的原因。
答案 2 :(得分:3)
这里的所有答案在技术上都是正确的。但我想从另一个角度解释这一点。
首先,您定义了一个Animal
和一个Dog
。到目前为止一切都很好。当您(在DogTest
内)创建Animal
并将ti转换为Dog
时,就会出现此问题。为什么?并非每个Animal
都是Dog
。我的意思是,Animal
可以是Bird
,Cat
,Elephant
......这些Animal
不会“吠”。说,您可以将Dog
投射为动物,因为所有Dog
都是Animal
s。
我希望我已经澄清了一下你的想法:)
答案 3 :(得分:0)
它不会打印任何内容,因为您无法使用d.makeNoise()
到达该行。当您尝试强制转换为java.lang.ClassCastException
某些不是Dog
的内容时,会在前一行中抛出Dog
。
但是,如果没有这一行,您将获得预期的结果:"通用噪音"。
答案 4 :(得分:0)
最好的向下转发我可以通过重写您的代码来解释如下: -
public interface Animal {
public void show();
}
public abstract class Dog implements Animal {
public void display(){
System.out.println("Dog Called");
}
}
public class Impl extends Dog{
@Override
public void show() {
System.out.println("Impl Called");
}
}
class DogTest {
public static void main(String [] args) {
Animal a = new Impl();
/**
* child class's method tried to be accessed with the help of
* parent class's object using downcasting of object
* */
((Dog)a).display();
}
}
然而,实时这样的需求可以在不使用显式向下转换对象的情况下实现,而不是在Factory Design Pattern的帮助下,我们创建对象而不将创建逻辑暴露给客户端并使用公共接口引用新创建的对象。
可以从here
中提取完整的工厂模式