一、什么是多态?
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
具体来说:
多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
多态构成: 子类继承父类,对父类中的方法进行重写,父类引用指向子类对象:Parent p = new Child();
二、向上转型与向下转型
对于理解什么是多态,向上转型与乡下转型起到了关键作用
1. 向上转型
格式: 父类名称 对象名 = new 子类名称()
含义: 定义一个父类对象指向子类示例
Parent p = new Child();
我们可以这样理解,定义了一个Parent 类型的p,它指向Child对象实例。由于Child是继承与Parent ,所以Child可以自动向上转型为Parent ,所以p是可以指向Parent 实例对象的
向上转型缺陷:
向上转型是安全的,但是存在缺陷,
父类类型的引用可以调用父类中定义的所有属性和方法,对于只存在于子类中的方法和属性就无法得到调用了
2. 向下转型
格式: 子类名称 对象名 = (子类名称) 父类对象
含义: 将父类对象强转为子类对象
Child p = (Child)Parent;
向下转型缺陷:
向下转型解决了向上转型无法调用自存在于子类中的方法和属性的问题,但是是危险的。
原因:向下转型时,定义的子类对象指向父类对象,如果该父类对象是指向相同的子类对象实例就是安全的,否则就是危险的,会导致无法调用子类中的属性与方法
错误示例:
Parent q = new Youth();
Child p = (Child)Parent;
正确示例:
Parent q = new Child();
Child p = (Child)Parent;
我们可以使用instanceof关键字进行避免向下转型的危险性,将父类对象q与子类对象比较,如果父类对象q是指向相同子类进行示例的才进行向下转型
if (q instanceof Child) {
Child p = (Child)Parent;
}
三、多态示例
业务场景:
根据程序运行期间需要调用相应的老师去上课,调用哪个老师就根据调用的方法类型进行选择向上或向下转型进行示例化,
使用向上转型调用重写方法,使用向下转型调用子类单独方法
package com.demo;
abstract class Teacher {
abstract void work();
}
class Chinese extends Teacher {
public void work() {
System.out.println("汉语老师:重写方法");
}
}
class English extends Teacher {
void teach() {
System.out.println("英语老师:子类单独方法");
}
void work() {
System.out.println("英语老师:重写方法");
}
}
public class Test {
public static void main(String[] args) {
Teacher one = new Chinese(); //向上转型
one.work();
Teacher p = new English(); //向下转型
if (p instanceof English) {
English two = (English)p;
two.teach();
}
}
}