目录
一、向上转型的本质
举例说明
父类-Animal
子类-Cat类
测试-PolyDetail
语法
Object类
二、向上转型的特点
第一条
第二条
第三条
例子
Base类
TopBase类
测试类
第四条
运行结果
多态的前提:两个对象(类)存在继承关系
一、向上转型的本质
父类的引用指向了子类的对象
例如PolyObject.java中的
animal就是父类Animal的引用,指向了子类Dog的对象
举例说明
父类-Animal
package com.hspedu.poly_.detail_;
public class Animal {
String name = "动物";
int age = 10;
public void sleep(){
System.out.println("睡");
}
public void run(){
System.out.println("跑");
}
public void eat(){
System.out.println("吃");
}
public void show(){
System.out.println("hello,你好");
}
}
子类-Cat类
package com.hspedu.poly_.detail_;
public class Cat extends Animal{
String color = "白色";
public void eat(){//方法重写
System.out.println("猫吃鱼");
}
public void catchMouse(){//Cat特有方法
System.out.println("猫抓老鼠");
}
}
测试-PolyDetail
package com.hspedu.poly_.detail_;
public class PolyDetail {
public static void main(String[] args) {
//父类的引用指向了子类的对象
Animal animal = new Cat();
}
}
语法
父类类型 引用名 = new 子类类型()
Object类
如果在上述代码中添加
Object obj = new Cat();
编译能通过吗?
答案是:可以,因为Object是Animal的父类,同时也是Cat的父类
二、向上转型的特点
第一条
编译类型看左边,运行类型看右边
eg:
Object obj = new Cat();
编译类型是Object,运行类型是Cat
第二条
可以调用父类中的所有成员(同时也要遵守访问权限)
可以调用Animal类中的四个方法和两个属性
如果将name的访问修饰符改成private,就不能访问了,如下图所示,没有name了
第三条
不能调用子类中特有的成员(属性和方法)
catchMouse()是子类Cat类特有的成员
原因:在编译阶段, 能调用哪些成员,是由编译类型来决定的,即编译时是从编译类型开始到Object终止(即这些类的成员都可以被调用)
例子
新建Base类和TopBase类,让Animal继承Base,Base继承TopBase,此时仍然可以调用Base类和TopBase类中的成员
Base类
独有方法hi()
package com.hspedu.poly_.detail_;
public class Base extends TopBase {
public void hi() {
System.out.println("Base hi");
}
}
TopBase类
独有方法hi1()
package com.hspedu.poly_.detail_;
public class TopBase {
public void hi1() {
System.out.println("TopBase hi");
}
}
测试类
编译和运行都没有报错,是可以调用的
但是可以调用子类重写的父类的方法,因为父类也是有这个方法的
第四条
最终运行效果要看子类(运行类型)的具体实现
运行逻辑:运行类型是Cat类,所以先从Cat类开始查找,规则就是继承的本质一节中所讲的(属性和方法一样)
运行结果
根据上述规则,因为子类中也有eat()方法,所以优先运行子类中的eat方法,其他五个方法同理,但是子类中没有,所以向上查找,直到Object类