Java 面向对象编程——多态
向上转型
父类引用子类对象叫向上转型。
class Animal{ public String name; public Animal(String name){ this.name = name; } public void eat(){ System.out.println(this.name + "正在吃"); } } class Bird extends Animal{ public Bird(String name) { super(name); } public void fly(){ System.out.println(this.name + "正在飞"); } } public class TestMain { public static void main(String[] args) { //父类引用子类对象 —— 向上转型 Animal animal = new Bird("麻雀"); }
当我们在Animal 的 eat 方法中添加一个标记后,再运行此方法↓
可以看到我们调用的就是 Animal 的 eat 方法
而当我们想调用 fly 方法的时候却报错了
可以得出:通过父类引用只能引用父类自己的方法或者属性。
向上转型发生条件:
1、直接赋值
Animal animal = new Bird("麻雀"); animal.eat();
2、传参
public class TestMain { public static void func1(Animal animal){ animal.eat(); } public static void main(String[] args) { Bird bird = new Bird("小鸟"); func1(bird); }
运行结果为:
3、返回值
public Animal func2(){ Bird bird = new Bird("鸟儿"); return bird; }
重写 Override
1、方法名相同
2、参数列表相同(参数的个数、类型)
3、返回值相同(返回值可以不同,但是需要遵循协变类型 → 返回值之间可以构成继承关系(了解))
4、继承关系上
下图两个箭头表示这两个方法构成重写方法
注意:
1、该方法的访问修饰限定符不能是 private
2、访问修饰限定符不一定是相同的,只要满足:子类的访问修饰限定符大于等于父类的访问修饰限定符
3、静态的方法不能被重写
运行时绑定(动态绑定):多态
1、向上转型:父类引用子类对象
2、子类和父类有相同的覆盖方法
3、通过父类的引用,调用该方法,此时就会发生动态绑定
实例化 Animal 对象的时候调用它的子类对象 Cat:
这里调用的是 Cat 下面的eat()
我们运用 javap -c 类名 这个命令来进行反编译查看一下编译过程
我们可以看到编译的时候调用的是 Animal 的 eat(),但是运行的时候调用的是 Cat 的 eat()
这就是运行时绑定或动态绑定
上一篇:
IDEA上Java项目控制台中文乱码