问题描述
我有以下代码:
class A {
}
class B extends A {
public void fB(){};
}
根据Java规则:
案例1:
B b = new B();
A a = b;
((B)a).fB();
案例2:
A a = new A();
B b = a;
根据Java规则,案例1 确定,案例2 不好。为什么案例2 不正常?这行((B)a).fB();
实际上是什么(我的意思是里面发生了什么)?
According to Java rule, Case 1 is ok and Case 2 is not ok. Why Case 2 is not ok? And what this line ((B)a).fB();
actually does (I mean what happens inside)?
推荐答案
为什么案例1没问题且案例2不正常:因为狗
是 Animal
,但不是每个 Animal
都是 Dog
。
Why case 1 is OK and case 2 is not OK: Because a Dog
is an Animal
, but not every Animal
is a Dog
.
class Animal { }
class Dog extends Animal { }
class Cat extends Animal { }
Dog fifi = new Dog();
Cat tommy = new Cat();
// OK because Dogs and Cats are Animals
Animal pet1 = fifi;
Animal pet2 = tommy;
// Not OK because an Animal is not always a Dog
Dog doggy = pet2;
请注意,对该对象不执行任何操作;特别是,它不会对对象进行任何类型的转换。 Casting只告诉编译器我这里有这个对象,我比你知道的更好;我希望你把它当作X型而不是给我任何错误信息。
Note that casting does nothing to the object; in particular, it doesn't do any kind conversion of objects. Casting is only telling the compiler "I have this object here, and I know better than you what it is; I want you to treat it as type X and not give me any error messages".
所以在这样一行:
Dog doggy = pet2;
编译器会抱怨,因为它无法确定 pet2
实际上是 Dog
;它只知道它是 Animal
- 而且并非所有 Animal
都是 Dog
秒。你可以做一个强制转换来告诉编译器不要抱怨这个:
the compiler will complain because it cannot be sure that pet2
is actually a Dog
; it only knows that it is an Animal
- and not all Animal
s are Dog
s. You can do a cast to tell the compiler to not complain about this:
// Tell the compiler that you want it to treat pet2 as a Dog
Dog doggy = (Dog)pet2;
但是当你运行程序时,Java仍会检查 pet2
实际上是 Dog
,如果不是,则会得到 ClassCastException
。
But when you run the program, Java will still check if pet2
is really a Dog
, and if it isn't, you get a ClassCastException
.
(你的标题中的问题与你的意思完全相反,正如biziclop注意到的那样)。
(And the question in your title is exactly the opposite of what you mean, as biziclop noticed).
这篇关于为什么超类对象不能在Java中隐式转换为子类对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!