多态性,是面向对象中最重要的概念,在 JAVA 中的体现:
对象的多态性: 父类的引用指向子类的对象
可以直接应用在抽象类和接口上
Java 引用变量有两个类型:编译时类型 和 运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简称:编译时,看左边;运行时,看右边。
若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism)
多态情况下,"看左边": 看的是父类的引用(父类中不具子类特有的方法)
"看右边": 看的是子类的对象(实际运行的是子类重写父类的方法)
理解多态性:可以理解为一个事物的多种形态。
何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
多态的使用:虚拟方法调用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
总结:编译,看左边; 运行,看右边。
多态性的使用前提:1.类的继承关系,2.方法的重写
对象的多态性:只话用于方法, 不适用于属性(编译和运行都看左边)
若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里能同名方法,系统将不可能把父类里的方法转移到子类中。编译看左边,运行看右边。
对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量。编译运行都看左边。
Person.java
package com.klvchen.java4; public class Person { String name; int age; int id = 1001; public void eat() { System.out.println("人, 吃饭"); } public void walk() { System.out.println("人,走路"); } }
Man.java
package com.klvchen.java4; public class Man extends Person { boolean isSmoking; public void earnMoney() { System.out.println("男人负责挣钱养家"); } public void eat() { System.out.println("男人多吃肉,长肌肉"); } public void walk() { System.out.println("男人霸气地走路"); } }
Woman.java
package com.klvchen.java4; public class Woman extends Person { boolean isBeauty; public void goShopping() { System.out.println("女人喜欢购物"); } public void eat() { System.out.println("女人少吃,为了减肥"); } public void walk() { System.out.println("女人窈窕地走路"); } }
PersonTest.java
package com.klvchen.java4; public class PersonTest { public static void main(String[] args) { Person p1 = new Person(); p1.eat(); Man man = new Man(); man.eat(); man.age = 25; man.earnMoney(); //************************************** System.out.println("***************************************"); //对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用) Person p2 = new Man(); //当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 --- 虚拟方法调用 p2.eat(); p2.walk(); // p2.earnMoney(); System.out.println(p2.id); } }
AnimalTest.java
package com.klvchen.java4; public class AnimalTest { public static void main(String[] args) { AnimalTest test = new AnimalTest(); test.func(new Dog()); System.out.println("*************************************"); test.func(new Cat()); } public void func(Animal animal) {// Animal animal = new Dog(); animal.eat(); animal.shout(); } } class Animal{ public void eat() { System.out.println("动物, 进食"); } public void shout() { System.out.println("动物, 叫"); } } class Dog extends Animal{ public void eat() { System.out.println("狗吃骨头"); } public void shout() { System.out.println("汪!汪!汪!"); } } class Cat extends Animal{ public void eat() { System.out.println("猫吃鱼"); } public void shout() { System.out.println("喵!喵!喵!"); } }