三.多态
1.概述
多种形态是面向对象语言最核心的特征
一个子类对象(实现类对象)既可以给这个子类引用变量赋值,又可以给父类变量赋值
最终多态体现为父类引用变量可以指向子类对象
如Student类可以为Person类的子类,那么一个Student对象既可以赋值给一个Student类型的引用,也可以赋值给一个Person类型引用
2.多态调用的三种格式
父类的引用变量指向子类对象:父类类型 变量名=new 子类类型();
普通类多态定义的格式:父类 变量名=new 子类();
抽象类多态定义的格式:抽象类 变量名=new 抽象类子类();
接口多态定义的格式:接口 变量名=new 接口实现类();
3.注意事项
同一个父类的方法会被不同的子类重写,在调用方法时,调用的是各个子类覆盖后的方法
Person p1=new Student();
Person p2=new Teacher();
p1.work();
p2.work();
4.多态中成员访问的特点
成员变量:编译看左边(引用变量的声明类型),运行看左边(实际访问到的成员变量的值也是由引用变量的声明类型来决定)
方法:编译看左边(引用变量的声明类型),运行看右边(实际访问到的方法是由引用变量所指向的对象的实际类型来决定)
5.编译时多态(方法重载overload)
6.运行时多态
继承。方法覆盖、重写(override)、父类引用指向子类对象
7.多态的转型
向上转型:子类对象赋值给一个父类引用
向下转型:已经向上转型的子类对象,将父类引用强制转为子类引用
子类类型 变量名=(子类类型)父类类型的变量
向下转型的作用:使用子类特有的功能
8.instanceof关键字
作用:通过instanceof关键字来判断是否能够对象转化。一个引用型的变量是不是这个类型的对象
格式:boolean b=对象 instanceof 数据类型
Person p1=new Student();
boolean flag=p1 instanceof Student;
boolean flag2=p2 instanceof Teacher;
四、 抽象类
1. 概述
- 在Java中,一个没有方法体的方法应该定义为抽象方法,而如果一个类中含有抽象方法,则该类必须定义为一个抽象类
- 抽象类通常作为一个 框架(虽然在父类抽象类中,有些行为并不能具体确定,但是从类设计的角度将,我们能确定该类存在这样的行为),把子类将实现的抽象方法组织起来,简化或限制子类的设计
2. 抽象类的定义格式
- 抽象方法定义的格式:
public abstract 返回值类型 方法名(参数);
- 抽象类定义的格式:
abstract class 类名 {}
3. 抽象类特点
- 抽象类和抽象方法都需要被
abstract
修饰。抽象方法一定要定义在抽象类中。 static、final、private
不能与abstract
同时出现。- 抽象方法 不能有 方法体
- 抽象类 不一定 有抽象方法,但是含有抽象方法的类 必须是 抽象类
- 构造方法,类方法(用
static
修饰的方法),不能声明为抽象方法。 - 抽象类本身不能实例化(但是多态机制可以用子类实例化),不可以直接创建对象
原因:调用抽象方法没有意义 - 只有覆盖了抽象类中 所有的 抽象方法后,其子类才可以创建对象。否则该子类还是一个抽象类。
- 抽象类只定义了类的部分行为(包含具体行为), 这些行为是 子类共有的,其它行为由子类实现的抽象方法提供
4. 抽象类成员特点
- 抽象类的 成员变量:既可以变量,又可以是常量
- 抽象类的 构造方法:用于父类数据的初始化
子类继承抽象类时,构造方法不会被覆盖。 而且,在实例化子类对象时首先调用的是抽象类中的构造方法再调用子类中的。
因此,在抽象类中可以使用构造方法封装,所继承子类公共的东西。
- 抽象类的 方法:可以是抽象的,也可以是非抽象的,
- 作用:
- 抽象的:强制子类实现 (语法上的强制约束力)
- 非抽象的:子类可以复用
- 作用:
5.抽象类的子类(二选一)
- 如果不想重写抽象类里面的抽象方法,则子类也必须是抽象类
- 如果不是抽象类,则必须实现抽象父类的所有抽象方法
6. 抽象类的细节
- 抽象类一定是个父类?
严格来说是的,不是父类的话就没有意义了,抽象类的抽象方法必须由子类来实现 本身只起到定义的作用
- 抽象类中是否可以没有抽象方法?如果可以,那么,该类还定义成抽象类有意义吗?为什么?
可以没有抽象方法,有意义,是为了不让该类创建对象,方法可以直接让子类去使用
在实际开发中,有的时候,不希望使用者,直接实例化出一个类的对象,可以将这个类定义为abstract