Class Lion扩展了Animal。
这是我的代码:
Animal a = new Animal();
Lion b = new Lion();
Animal c = (Animal) b;
Animal[] arr = { a, b, c };
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i].getClass().getName());
arr[i].run();
}
结果是:
test2.Animal
动物奔跑......
test2.Lion
Lion Run ......
test2.Lion
Lion Run ......
从示例中可以看出,“c”是“狮子”,而不是“动物”。为什么会这样?
答案 0 :(得分:9)
从示例中可以看出&#34; c&#34;是一个狮子&#34;而不是&#34;动物&#34;。为什么会这样?
因为c
狮友:
Lion b = new Lion(); // Creates a Lion
Animal c = (Animal) b; // Refers to the Lion through an Animal variable
现在,c
是对Animal
对象的Lion
类型引用。该对象仍然是Lion
,它只是对Animal
内容的引用。因此,当您询问该对象的类是什么(而不是您的接口对于它在数组中的c
变量/第三个条目中)时,它会告诉您它是一个{{ {1}}。
这与这种情况完全相同:
Lion
Map m = new HashMap();
引用的类型为m
,因此您只能使用它来访问Map
接口定义的内容,但对象它&#39 ; s引用的是Map
实例。
答案 1 :(得分:2)
您正在调用getClass
。
方法调用在运行时解析,因此它打印Lion
而不是Animal
。
答案 2 :(得分:1)
您的对象c
是对象的引用,对象必须是Animal
类型或任何子类。仅仅因为对象引用是Animal
并不能保证对象是Animal
,它只是意味着它将表现为Animal
,并且您可以调用所有方法那个你想要的课程。这是多态性的一部分。
答案 3 :(得分:1)
强制转换不会使引用的对象更改其类型,它只是将自身限制为超类型的方法。由于这些原因,您无法将Banana
投射到Animal
。
你队中的演员阵容
Animal c = (Animal) b;
无论如何都会自动发生。您只需要在向下转换时指定演员阵容:
Animal a = new Dog();
Dog d = (Dog) a;
但a
和d
仍然指向堆中的Dog
,因此如果它们覆盖了Dog
类的方法,则会使用它们的实例方法Animal
课程。
换句话说,a
是Dog
,但只要它被声明为(或类型转换为)Animal
,它就只能使用Animal
方法。