多态概述
-
概述:
同一个对象,在不同时刻表现出来的不同形态
-
举例:
我们可以说猫是猫:猫 cat = new 猫();
我们也可以说猫是动物:动物 animal = new 猫();
这里猫在不同的时刻表现出来了不同的形态,这就是多态
实现多态的三个前提
- 有继承/实现关系
- 有方法重写
- 有父类引用指向子类对象
举例
Person类:
package com.oop.demo8;
public class Person {
public void run(){
System.out.println("run");
}
}
Student类:
package com.oop.demo8;
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
}
Application类:
package com.oop.demo8;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的,例如 new Student(),一定是一个学生对象
//但是一个对象可以被不同的类所指向,例如 Person s2 = new Student(),是父类的引用指向了子类
Student s1 = new Student(); //子类能调用的方法都是自己的或者继承父类的
Person s2 = new Student(); //父类可以指向子类,但是不能调用子类独有的方法
Object s3 = new Student();
//对象能执行哪些成员方法(成员变量同理),取决于左边的类型,和右边对象无关
s2.run(); //子类重写了父类的方法,所以执行子类的方法
s1.run();
}
}
多态中成员访问特点
-
举例
Animal类:
package com.oop.demo9; public class Animal { public int age=40; public void eat(){ System.out.println("动物吃东西"); } }
Cat类:
package com.oop.demo9; public class Cat extends Animal{ public int age=20; public int weight=10; @Override public void eat() { System.out.println("猫吃鱼"); } public void playGame(){ System.out.println("猫捉迷藏"); } }
Application类:
package com.oop.demo9; public class Application { public static void main(String[] args) { //父类引用指向子类对象 Animal a=new Cat(); //访问成员变量:编译看等号左边数据类型,执行看等号左边定义类 System.out.println(a.age); //age是父类中的成员变量,故age不报错;运行输出为父类中的成员变量值40 //System.out.println(a.weight); //weight处报错 //访问成员方法:编译看等号左边数据类型,执行看等号右边定义类 a.eat(); //eat()是父类中的方法,故eat()不报错;运行输出为子类的方法 //a.playGame; //playGame处报错 } }
-
小结:
-
多态中成员访问的特点:
成员变量:编译看左边,执行看左边
成员方法:编译看左边,执行看右边
-
为什么成员变量和成员方法的访问不一样呢?
因为成员方法有重写,而成员变量没有
-
多态的好处和弊端
-
举例
Animal类:
package com.oop.demo10; public class Animal { public void eat(){ System.out.println("动物吃东西"); } }
Cat类:
package com.oop.demo10; public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } }
Dog类:
package com.oop.demo10; public class Dog extends Animal{ @Override public void eat() { System.out.println("狗吃骨头"); } }
Pig类:
package com.oop.demo10; public class Pig extends Animal{ @Override public void eat() { System.out.println("猪吃白菜"); } }
AnimalOperator类:
package com.oop.demo10; public class AnimalOperator { public void useAnimal(Cat c){ //Cat c = new Cat(); c.eat(); } public void useAnimal(Dog d){ //Dog d = new Dog(); d.eat(); } public void useAnimal(Pig p){ //Pig p = new Pig(); p.eat(); } }
Application类:
package com.oop.demo10; public class Application { public static void main(String[] args) { //创建动物操作类的对象,调用方法 AnimalOperator ao = new AnimalOperator(); Cat c = new Cat(); ao.useAnimal(c); Dog d = new Dog(); ao.useAnimal(d); Pig p = new Pig(); ao.useAnimal(p); } }
若应用多态的方法,将上述AnimalOperator类改成如下代码:
修改后的AnimalOperator类:
package com.oop.demo10; public class AnimalOperator { public void useAnimal(Animal a){ //编译看左边,运行看右边 //Animal a = new Cat(); //Animal a = new Dog(); //Animal a = new Pig(); a.eat(); } }
-
小结:
-
多态的好处:提高了程序的扩展性
具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
-
多态的弊端:不能使用子类特有的功能
-
多态注意事项
- 多态是方法的多态,属性没有多态
- 在修饰符为static、final、private时,无法实现多态
- 子类能调用的方法都是自己的或者继承父类的
- 父类可以指向子类,但是不能调用子类独有的方法
重要声明:本篇文章整理自B站狂神说Java、B站黑马程序员全套Java教程