多态
简述
定义:
指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是方法调用)
多态的技术称为:
动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
含义:
事物的多种状态
分类:
1)对象多态性:同一个物体,有多种称谓。即——》同一个对象可以有不同类型的引用指向该对象
2)引用多态性:同一个名称,表达多种物体。即——》同一个引用可以指向多个子类对象
前提:
1)继承关系(接口、实现类)
2)父类的引用,指向子类的对象(接口类型的引用指向实现类对象){解释:例如——Animal a = new Dog() }
3)重写
</pre>
详解
1)【重写的访问】:
编译看左边,运行看右边
故,左边对象中没该方法时,会报错
Animal a = new Cat()——那么访问的就是右边的成员方法
2)成员变量:
(一般没用,因为一般子类和父类中的变量名不同)
编译看左边,运行也看左边
故,左边对象中没该变量时,会报错
Animal a = new Cat()——那么访问的就是左边的成员变量的值
3)静态成员方法:
(因为静态不可重写,那么调用不能体现多态,但是指向可以体现 Animal a =new Cat() )
编译看左边,运行也看左边
故,左边对象中没有该静态方法时,会报错
解释:
1.由于静态成员方法不能被重写,那么在子类中,再创建该方法时,是重新定义的,而不是重写。
2.静态成员方法随着类加载而创建,那么不需要在实例化,即——》Animal a = null都可以
👆👆的详解:编译都看左边,当左边没有时,就会报错。相当于种类的共有特性特点,每个分类都有这些特性、特点,但是不能存在特殊(比如人飞行),那么如何解决特殊情况👇👇
向上向下转型
向上转型:
使用父类的引用指向子类的对象
即:只能访问父类中定义的成员,缩小成员访问范围。就是一般的引用多态
此时:只能使用父类有的成员
向下转型:
让指向子类的父类引用,恢复到子类的引用
即,可使用子类的成员了
格式:子类名 命名 = (子类类型)父类的引用
此时:可以使用子类中特有的成员了
好处,用处
比如买了一个手机,今天想刷抖音,明天想看电视,所以不能把手机的功能限定死了,即——》增强可扩展性
public class demo_多态_使用情景 {
public static void main(String[] args) throws Exception{
Phone p = new Phone();
//常规
// Music m = new Music();
// p.funct(m);
// Television t = new Television();
// p.funct(t);
//引用多态性
// App a = new Music();
// p.funct(a);
// a = new Television();
// p.funct(a);
//使用文件流
//app.txt应该放在项目根目录下。注意app.txt中只有一行全类名,且不要加分号
BufferedReader br = new BufferedReader(new FileReader("app.txt"));//读入流,读入
//读取配置文件的第一行
String classname = br.readLine();//获取到
//通过反射获取到全类名对应的字节码对象(加载)
Class cl = Class.forName(classname);
//通过字节码创建出指定对象
// Object object = cl.newInstance();
//将顶层父类对象向下强转至App类。不能转为具体的哪个子类,因为不知道到底要转为什么子类
// App a = (App)object;
//最好别这样,因为不知道cl获取的什么类
App a = (App)cl.newInstance();//jdk1.9已经弃用。会直接调用该类的无参构造函数进行实例化
p.funct(a);
}
}
class Phone{
//体现函数编程思想
public void funct(App a) {
a.funct();
}
}
//可以将其定义为函数式接口(此处还没学习接口,所以定义的抽象类)
abstract class App{
public abstract void funct();
}
class Music extends App{
public void funct() {
System.out.println("听歌");
}
}
class Television extends App{
public void funct() {
System.out.println("看电视");
}
}
PS:
1)【】表示重要,删除线表示已解决
2)学习记录所用
3)<pre> 标签不好使