多态的应用
多态的应用
方法: 返回值类型 参数列表 方法名
多态的两种实现方式
- 使用父类作为方法形参实现多态
- 使用父类作为方法返回值实现多态
当这个作为参数的父类是普通类或者抽象类时,构成继承多态
当这个作为参数的父类是一个接口时,构成接口多态
多态作为形参(形式参数)
基本类型
满足类型转换的规则
引用类型
普通类
当一个形参希望我们传入的是一个普通类时,我们实际上传入的是该类的对象/匿名对象
抽象类
当一个形参希望我们传入的是一个抽象类时,我们实际上传入的是该类的子类对象/子类匿名对象
接口
当一个形参希望我们传入的是一个接口时,我们实际上传入的是该类的实现类对象/实现类匿名对象
多态作为返回值
返回值类型
基本类型
引用类型
普通类
当一个方法的返回值是一个普通的类时,实际上返回的是该类的对象,我们可以使用该类的对象接收
抽象类
当一个方法的返回值是一个抽象类时,实际上返回的是该抽象类的子类对象,我们可以使用该抽象类接收
接口
当一个方法的返回值是一个接口时,实际上返回的是该接口的实现类对象,我们可以使用接口接收
当方法的返回值类型是引用类型的时候,可以使用链式调用
注意: 当一个方法的形参是引用类型的时候,建议养成一个好的习惯: 做非空判断
public class ArgsDemo01 {
public static void main(String[] args) {
// 需求: 访问学生类中的 study方法
Student s = new Student();
s.study();
new Student().study();
// 需求: 访问StudentDemo中的method方法
StudentDemo sd = new StudentDemo();
// sd.method(null);
// 当一个形参希望我们传入的是一个普通类时,我们实际上传入的是该类的对象/匿名对象
// 习惯: 在写方法的时候,如果方法的形参是引用类型,记住要做非空判断,提高程序的安全性
new StudentDemo().method(new Student() {
@Override
public void study() {
System.out.println("Student 子类 study");
}
});
}
}
class Student {
public void study() {
System.out.println("Student.study()");
}
}
class StudentDemo {
// Student s = null;
public void method(Student s) {
// Student s = new Student();
// if (s != null) {
// s.study();
// }
if (s == null) {
throw new NullPointerException("对象不能够为null");
}
s.study();
}
}
实例化对象加载顺序
一旦实例化一个对象,其执行顺序,首先:
在不涉及继承的前提下,当首次加载类时,按照如下顺序执行:
- 按照出现顺序先后执行静态成员变量定义与静态块;
- 按照出现顺序先后执行动态成员变量定义与动态块;
- 执行构造函数;
再次实例化对象时只执行第2、4步即可;
在涉及到继承时,按照如下顺序执行:
- 执行父类的静态成员变量定义与静态块,执行子类的静态成员变量与静态块
- 执行父类非静态成员变量定义与动态块,执行父类构造方法;
- 执行子类的非静态成员变量定义与动态块,执行子类构造方法;
- 注意:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在调用父类构造函数中使用子类重写的方法。
在类加载机制中,更加详细讲解到实例化对象加载机制需要结合jvm内部运行机制的解析一起分析。

浙公网安备 33010602011771号