引用a的类型是Animal,是Cat的父类。所以是“父类引用指向子类对象”。如果是“子类引用指向父类对象”,那应该写成 Cat a = new Animal();但这显然是不和逻辑的。
你说的没错——“向上转型后,父类也只能调用父类已经有的方法”。但是子类如果覆盖了父类的方法,那么即使向上转型,方法的行为也表现为覆盖后的行为。这也是多态的一种体现。向上转型更多的用来体现一种编程上的“约定”。所有继承某个类或者实现某个接口的类,一定包含某个方法,这样在调用的时候,使得你也不必关系具体的实现细节,只要知道“这个类型中的某个方法能帮我完成工作”就可以了。
向下转型,是“引用的类型”的变化,不是对象实例类型的变化。new什么,就是什么。不会因为向上或者向下转型而改变自己的类型。
最后一个问题,不管向上还是向下转型,调用的都是实际类型中的那个方法。比如,Animal a = new Cat(); a.叫()。那这个叫就是Cat类型实例中的“叫”方法。
解答:
问题1 : 类是一个java 基本程序文件, 对象是 一个java 类的 实体化(已分配了内存等资源)
如 ; Object 是个类 Object o = new Object(); o 就是一个对象
所以 Animal a = new Cat(); 中 a 本质上是子类的对象, 只是说 a 是属于 Animal 这一类的 对象
因此, 这叫 父类引用 指向子类对象
问题2 :
这里面 a 本质上是子类对象,其 执行 吃 方法时,依然执行的是 Cat 的方法,而不是 父类 Animal 的方法。这种方式可以完成工厂模式等很多功能。
如 fun(Animal a)
{
a.eat();
}
这样的好处是: 你传给 fun 方法的是 Cat 也好,Dog 也好,都会执行吃的方法,唯一的不同时 传 Cat 执行的是 Cat 方法,Dog 执行 dog 方法,
int 转 long跟 鸟类是父类,麻雀是子类 完全没有关系,因为 int long都是java中的基础数据类型,比如int型转long型,因为long型范围包括了int型所有范围,因此long可以包含int, 如果强制将long转成int的话,就会失去精度,因为 int 是32位 long是64位。
不要在意这些细节,实践比理论更重要。
多用,自然就熟了,但是为什么,我也说不上来。