无参构造器+多态+接口与抽象类(2.2)
一、父类的无参构造器在继承关系里的作用?
1.满足子类默认构造器的隐式调用
子类中创建无参构造器时,会在第一行自动加上super(),去调用父类的无参构造器。若父类中没有无参构造器,则super()就会报错。
2.保证父类初始化流程完整
即使父类的无参构造器里什么代码都没写,JVM 也会先完成父类成员变量的默认初始化
3.支持子类对象正常实例化
当使用 new 子类()创建子类对象时,必须先触发父类构造器的执行,而父类的无参构造器就是这个执行入口。
没有这个入口,子类对象就无法被完整创建。
二、多态
1.多态性:
-
在父类中定义的行为,被子类继承之后,表现出不同的行为。
-
效果:同一行为在父类及其各个子类中具有不同的语义。
引用变量既可以指向相同类型的类的对象,也可以指向该类的任何一个子类的对象。例如:
Animal a = new Bird();
2.示例:

-
如果把子类对象赋给父类引用(将子类对象当作父类对象看待),那么就只能调用父类中已有的方法。
-
如果子类把父类方法覆盖了,再把子类对象赋给父类引用,通过父类引用调用该方法时,调用的是子类重写之后的方法。
3.instanceof运算符:
判断对象真实类型,为向下转型做安全检查返回布尔值,避免 ClassCastException
Java编译器允许在具有直接或间接继承关系的类之间进行类型转换

向上转型(多态):子类对象->父类引用
向下转型:父类引用->子类引用
-
必须使用强制类型转换
-
必须在有意义的情况下进行,即强转必须是合理的
-
编译器对于强制类型转换采取的是一律放行的原则(只检查语义)
例如:
①Bird bird = (Bird) xxx;
无论xxx是哪种类型,编译器都不会报错。
②Animal animal = new Animal();
Bird bird = (Bird)animal;编译无错,运行出错, ClassCastException异常
向上转型:
// 父类
class Animal {
public void move() {
System.out.println("动物在移动");
}
public void eat() {
System.out.println("动物在进食");
}
}
// 子类
class Bird extends Animal {
// 重写父类方法
@Override
public void move() {
System.out.println("鸟在飞");
}
// 子类独有方法
public void sing() {
System.out.println("鸟在唱歌");
}
}
public class Test {
public static void main(String[] args) {
// 向上转型:父类引用指向子类对象
Animal a = new Bird();
// 可以调用父类的方法,运行时执行子类的重写实现
a.move(); // 输出:鸟在飞
a.eat(); // 输出:动物在进食
// 不能直接调用子类独有的方法,编译报错
// a.sing();
}
}
向下转型:
public class Test {
public static void main(String[] args) {
Animal a = new Bird(); // 先向上转型
// 1. 安全检查:判断a的真实类型是不是Bird
if (a instanceof Bird) {
// 2. 向下转型:把父类引用转成子类引用
Bird bird = (Bird) a;
// 3. 可以调用子类独有的方法
bird.sing(); // 输出:鸟在唱歌
// 也可以调用重写的方法
bird.move(); // 输出:鸟在飞
}
}
}
总结:
向上转型:做通用,让代码适配多个子类、减少重复、降低耦合,是多态的基础;
向下转型:做专属,是向上转型的补充,解锁子类独有功能,实现个性化逻辑,仅在需要使用子类独有特性时才用;
三、接口与抽象类
| 对比维度 | 抽象类(Abstract Class) | 接口(Interface) |
|---|---|---|
| 定义方式 | 使用 abstract class 关键字定义 |
使用 interface 关键字定义 |
| 继承 / 实现规则 | 子类通过 extends 单继承(一个类只能继承一个抽象类) |
类通过 implements 多实现(一个类可实现多个接口);接口通过 extends 多继承其他接口 |
| 成员变量 | 可包含任意权限(public/protected/ 默认 /private)的变量,变量可修改 |
成员变量默认是 public static final(常量),必须初始化且不可修改 |
| 成员方法 | 可包含:- 抽象方法(abstract 修饰,无实现)- 非抽象方法(普通方法、静态方法、final 方法等,有实现) |
JDK8+ 可包含:- 抽象方法(默认 public abstract,无实现)- default 方法(有实现,供实现类调用或重写)- static 方法(有实现,通过接口名调用)JDK9+ 支持 private 方法(仅接口内部使用) |
| 构造方法 | 有构造方法(用于子类初始化时调用,完成抽象类成员的初始化) | 无构造方法(接口不存储实例状态,无需初始化) |
| 设计定位 | 体现 “is-a” 关系(子类是父类的一种),用于抽取子类的共性(包含属性 + 方法),作为子类的 “模板” | 体现 “like-a” 关系(类具备接口的行为),用于定义多个类的共同行为规范,作为不同类的 “协议” |
| 实例化方式 | 不能直接实例化,需通过 “子类继承并完全重写抽象方法” 后,实例化子类对象 | 不能直接实例化,需通过 “实现类实现并完全重写抽象方法” 后,实例化实现类对象 |
浙公网安备 33010602011771号