对象(五)
一、多态的概述(Polymorphism)
多态可以理解成,事物具有多种形态,对象可以存在不同的形态。如:
人可以有男人,女人;也可以分成学生,老师各种职业;
动物可以有老鼠和猫,大象和狮子。
多态则是面向对象三大特征之一,接下来我们依次谈谈多态的是什么样的,有什么好处和弊端,好处也就体现了他的作用,为什么会有多态的出现。
二、多态详述
1. 多态的前提
首先,必须要有继承,
其次,要有方法的重写,
再者,要有父类引用指向子类对象。
代码01:
1 public class TestPolymorphic { 2 public static void main(String[] args){ 3 Person p = new Student(); //父类引用指向子类对象 4 p.playChiJi(); 5 } 6 } 7 8 // 父类 9 class Person { 10 public void playChiJi(){ 11 System.out.println("人在吃鸡"); 12 } 13 } 14 15 //子类 16 class Student extends Person { //继承 17 public void playChiJi(){ //重写 18 System.out.println("小学生在吃鸡"); 19 } 20 }
有继承,有方法的重写,有父类引用指向子类对象。那么多态有什么好处呢?
2. 多态的好处
a.提高了代码的维护性 (继承保证)
b.提高了代码的可维护性 (多态保证)
3. 多态的弊端
不能使用子类的特有属性和行为
接下来,我们就详细分析,通过案例的形式来谈谈多态。
4.多态 -- 成员变量访问特点
a.成员变量:编译时看左边(父类),运行看左边(父类)。也就是说,父类引用指向子类时,访问的依旧是自己的成员变量。如代码02:
1 public class TestPolymorphic { 2 public static void main(String[] args){ 3 Person p = new Student(); //父类引用指向子类对象 4 System.out.println(p.num); 5 } 6 } 7 8 // 父类 9 class Person { 10 int num = 10; 11 public void playChiJi(){ 12 System.out.println("人在吃鸡"); 13 } 14 } 15 //子类 16 class Student extends Person { //继承 17 int num = 20; 18 public void playChiJi(){ //重写 19 System.out.println("小学生在吃鸡"); 20 } 21 }
结果是:10
b.内存图:
当运行编译的时候,看的是Person,编译看左边(父类),字节码进入方法区内;父类Person p指向的是自己的成员变量,运行时,指向的是super。因此,成员变量输出的结果是:10。
而Student s = new Student();指向就是自己,this。因此s.num = 20。
5.多态 -- 成员方法访问特点
a.成员方法:编译看左边(父类),运行看右边(子类)。接下来,看上面的代码01:
b.解释一下:编译时,会去父类中查看有没有这个方法(playChiJi()),如果没有,那就报错;在运行的时候,执行的是子类的方法,因此也叫动态绑定。
小结一下:成员变量,编译看左边(父类),运行看左边(父类)。
成员方法,编译看左边(父类),运行看右边(子类)。
6.多态应用: 当做参数传递(实用)
1 public class TestPolymorphic { 2 public static void main(String[] args){ 3 method(new Student()); 4 method(new Girl()); 5 } 6 7 public static void method(Person p){ 8 p.playChiJi(); 9 } 10 } 11 12 // 父类 13 class Person { 14 int num = 10; 15 public void playChiJi(){ 16 System.out.println("人在吃鸡"); 17 } 18 } 19 //子类 20 class Student extends Person { //继承 21 int num = 20; 22 public void playChiJi(){ //重写 23 System.out.println("小学生在吃鸡"); 24 } 25 } 26 27 //子类 28 class Girl extends Person { //继承 29 int num = 20; 30 public void playChiJi(){ //重写 31 System.out.println("美眉在吃鸡"); 32 } 33 }
一般开发中,很少用Person p = new Student(),而是以参数的形式进行传递,这样体现了多态的特性,父类引用指向子类的。可以直接传递这个对象。
但是,父类不能使用子类的特有的方法和变量。如果,子类特有一个方法,那么就不能访问。
这个时候又有了向下转型和向上转型。
Person p = new Student();其实就是向上转型,Student转成Person,向上转型。
Student s = (Student)p;向下转型。先有父类,才能向下转型。
后续还有很多需要补充,目前先到这里。
如有错误之处,欢迎指正。
邮箱:it_chang@126.com