Object o = new Student(); // Implicit casting
我非常了解这段代码,而我所理解的是,引用变量“o”是指“Object”类型的数据,我们可以看到Student从“Object”扩展,这意味着它引用了一个实例学生。 如果我写了以下代码:
Object x = o;
这会将o中的值分配给x,这意味着如果我们遵循x的方向,我们将转到上面的学生对象!
我的问题是,为什么我不能写下面的代码? :
Student x = o;
“o”指的是“对象”类型的对象,该对象将其地址(在内存中)分配为“o”,为什么我们不能将保存在o中的值分配给x!
答案 0 :(得分:5)
这里没有施法。
正如您所说,Object
是Student
的基类
这意味着Student
的每个实例也都是Object
,我们可以将其视为一个。
Object o = new Student(); // A Student is an Object
然而,相反的关系并不成立 - 并非Object
的所有实例都是Student
。
将Student
分配给o
后,编译器无法获得 Student
的信息。
该信息在运行时可用 - 您可以说o instanceof Student
,它会
是真的 - 但编译器不知道这一点。
答案 1 :(得分:3)
Object o;
if (Math.random < 0.5) {
o = new Student();
} else {
o = new Dog();
}
你显然不能Student x = o;
除非狗也是学生,否则这是一个不同的故事。
答案 2 :(得分:3)
Object o = new Student(); //upcasting - Implicit cast
Student x = (Student) o; //downcasting -Explicit cast
向上推广:我们正在缩小参考转换(向上移动继承层次结构)。由于学生IS-A
对象,它不需要显式转换
向下转型:我们正在扩大引用转换(向下移动继承层次结构)。由于Object可以是任何东西,我们必须使用显式强制转换将其强制转换为Student。
答案 3 :(得分:2)
Java只允许隐式向上转换,而不是隐式向下转换。
Java中的向上转换也称为扩展转换,而向下转换称为缩小转换。
可以隐式或显式地将对象强制转换为超类型。在此示例中,Object
是Student
的超类型。
Object o = new Student();
Object x = o; // implicit works
Object x = (Object) o; // explicit works
无法将对象隐式强制转换为子类型,并且必须显式转换。在此示例中,Student
是Object
的子类型。
Object o = new Student();
// Student x = o; // implicit doesn't work
Student x = (Student) o; // explicit works
Explicit and Implicit Type Casting - Herong Yang
答案 4 :(得分:1)
您需要明确地将其转换为学生
Student x = (Student) o;
之所以这样,是因为编译器不知道这是否正确,所以你需要将其转换为&#34;我相信这会有效。请相信我&#34; 。
答案 5 :(得分:1)
您可以将Student实例分配给声明为Object类型的变量,因为每个Student都是Object的一种(或特化)。由于并非每个对象都是学生,因此编译器会将其知道的事物分配给对象的任何特化,例如Student。因此,您可以毫无困难地隐式地分配一个更通用类型的实例变量,但是在相反的方向上,编译器需要保证您的意思是这样做,因此您明确地向下转换。
Student x = (Student)o;
这只是静态类型语言的本质。
答案 6 :(得分:1)
你基本上必须看看它是否通过IS-A
测试,你可以说Student IS-A Object
(因为Java中的每个类都是Object类的子类),这就是第一个隐式转换工作的原因。 / p>
但是你不能说Object IS-A Student
,因为它可能不是。除非您知道它将是Student
,否则您可以使用以下方式进行 downcast :
Student x = (Student) o;
如果您在 downcast 中犯了错误,您可能希望将其包装在if语句中,如下所示:
if(o instanceof Student) {
Student x = (Student) o;
}