Java编程进阶之路——深入理解继承与多态(第八讲)

未分类2周前发布 gsjqwyl
10 0 0

Java编程进阶之路💻——深入理解继承与多态(第八讲)

Java编程进阶之路——深入理解继承与多态(第八讲)

一、继承机制:提升代码复用效率

1.1 继承的必要性

Java编程进阶之路——深入理解继承与多态(第八讲)
假设我们需要为不同宠物创建类,未使用继承时可能出现以下情况:

// 犬类
public class Canine {
String petName;
int years;
double mass;
public void consumeFood() {
System.out.println(petName + "正在进食");
}
public void rest() {
System.out.println(petName + "正在休息");
}
void makeSound() {
System.out.println(petName + "发出汪汪声");
}
}
// 猫科类
public class Feline {
String petName;
int years;
double mass;
public void consumeFood() {
System.out.println(petName + "正在进食");
}
public void rest() {
System.out.println(petName + "正在休息");
}
void vocalize() {
System.out.println(petName + "发出喵喵声");
}
}

Java编程进阶之路——深入理解继承与多态(第八讲)
观察可见,两个类中存在大量相似代码(petName、years、mass属性,consumeFood()和rest()方法)。继承机制正是为解决此类代码重复问题而设计。

1.2 继承的基本原理

继承是面向对象编程中实现代码重用的关键技术,它允许新创建的类基于现有类进行扩展,添加特有功能。新类称为子类(派生类),被继承的类称为父类(基类)。
继承关系可表示为:

生物类
/    \
犬类    猫科类

1.3 实现继承的语法

Java通过extends关键字实现继承关系:

// 生物基类
public class LivingBeing {
String petName;
int years;
public void consumeFood() {
System.out.println(petName + "正在进食");
}
public void rest() {
System.out.println(petName + "正在休息");
}
}
// 犬类派生
public class Canine extends LivingBeing {
void makeSound() {
System.out.println(petName + "发出汪汪声");
}
}
// 猫科派生
public class Feline extends LivingBeing {
void vocalize() {
System.out.println(petName + "发出喵喵声");
}
}

1.4 继承体系中的访问规则

在继承结构中,子类访问父类成员需遵循以下原则:
1. 字段访问
– 子类存在该字段时优先访问
– 子类不存在时访问父类字段
– 均不存在则编译错误
2. 方法调用
– 方法名不同时,先在子类查找再到父类
– 方法名相同但参数不同时构成重载
– 方法签名完全相同时形成重写

1.5 super关键字的运用

当父子类存在同名成员时,可通过super显式访问父类成员:

public class Child extends Parent {
int value;  // 与父类同名
public void process() {
super.value = 200;  // 父类字段
this.value = 100;   // 子类字段
}
}

1.6 派生类构造方法规范

子类构造时必须优先调用父类构造器:

public class Parent {
public Parent() {
System.out.println("父类构造器");
}
}
public class Child extends Parent {
public Child() {
// 编译器自动添加super()
System.out.println("子类构造器");
}
}

重要注意事项:
1. super()必须作为子类构造器的首条语句
2. 父类若无默认构造器,子类需显式调用有参构造器

二、继承的类型

现实世界的继承关系复杂多样,例如:
Java编程进阶之路——深入理解继承与多态(第八讲)
但Java仅支持特定继承模式:
Java编程进阶之路——深入理解继承与多态(第八讲)

三、多态特性:灵活的对象行为

3.1 多态的核心概念

多态指相同操作在不同对象上呈现不同行为。典型示例:

打印设备
├─ 彩色打印机 → 输出彩色文档
└─ 单色打印机 → 输出黑白文档

3.2 实现多态的条件

Java中实现多态需满足:
1. 存在继承层次结构
2. 子类重写父类方法
3. 通过父类引用调用方法

3.3 方法重写规范

对比项 方法重写 方法重载
参数列表 必须相同 必须不同
返回类型 相同或子类 可不同
访问修饰符 不能更严格 可不同
Java编程进阶之路——深入理解继承与多态(第八讲)
方法重写需遵守:
– 保持方法签名一致
– 返回类型协变允许
– 访问权限不严于父类
– 不可重写static/private/final方法
示例:
class Animal {
public void eat() {
System.out.println("动物进食");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫咪吃鱼");
}
}

3.4 类型转换机制

  1. 向上转型:子类实例转为父类引用
Animal pet = new Cat("小花", 3);
  1. 向下转型:父类引用转为子类类型
    Java编程进阶之路——深入理解继承与多态(第八讲)
if (pet instanceof Cat) {
Cat myCat = (Cat) pet;
myCat.vocalize();
}

3.5 多态的优劣分析

优势:
1. 简化条件判断逻辑
2. 增强系统扩展性
局限:
1. 运行时性能略低
2. 属性不具备多态性
3. 构造器中调用重写方法存在风险

3.6 构造器中的方法调用陷阱

典型问题案例:

class Base {
public Base() {
execute();  // 潜在风险
}
public void execute() {
System.out.println("基类方法");
}
}
class Derived extends Base {
private int value = 1;
@Override
public void execute() {
System.out.println("派生类方法 " + value);
}
}
public class Demo {
public static void main(String[] args) {
Derived obj = new Derived();  // 输出:派生类方法 0
}
}

此时value尚未初始化(默认值0),因为父类构造器执行时子类字段未完成初始化。

四、继承与组合的抉择

继承表示”属于”关系,组合表示”包含”关系:

// 继承:跑车属于汽车
class SportsCar extends Vehicle {
// ...
}
// 组合:汽车包含引擎
class Vehicle {
private Engine powerUnit;
private Wheel[] wheels;
// ...
}

设计建议:优先考虑组合,除非明确存在”is-a”关系。

五、final修饰符的应用

final可修饰:
1. 变量:定义常量
2. 方法:禁止重写
3. 类:阻止继承

final class Math {  // 不可继承的类
// ...
}

核心要点

【多态优势】
显著降低代码的”圈复杂度”,减少条件判断
何谓”圈复杂度”?
这是评估代码复杂度的指标。直线型代码易于理解,而包含大量条件分支或循环的代码则复杂度较高。简单计算条件语句和循环语句的数量即可得到圈复杂度。高圈复杂度的方法应考虑重构。
继承与多态是Java面向对象编程的基石,掌握它们对编写优雅代码至关重要。关键要点:
– 继承实现代码复用和类型关系
– 多态提升程序灵活性
– final增强代码安全性
– 组合优先于继承是优秀设计原则
Java编程进阶之路——深入理解继承与多态(第八讲)


Java编程进阶之路——深入理解继承与多态(第八讲)
Java核心知识专栏

© 版权声明

相关文章

暂无评论

暂无评论...