第一部分:继承基础概念

理解继承的本质和 Java 中的实现方式

学习目标

理解继承的意义,掌握 extends 关键字的使用,建立继承层次结构

1

什么是继承

继承是面向对象三大特性之一,允许一个类(子类)继承另一个类(父类)的属性和方法。

// 父类(基类、超类) public class Vehicle { protected String brand; protected int year; public Vehicle(String brand, int year) { this.brand = brand; this.year = year; } public void start() { System.out.println(brand + " is starting..."); } } // 子类继承父类 public class Car extends Vehicle { private int doors; public Car(String brand, int year, int doors) { super(brand, year); // 调用父类构造方法 this.doors = doors; } }
2

继承的内存结构

子类对象包含父类的所有成员变量和方法。

Vehicle 内存结构

brand: String
year: int
start(): void

Car 内存结构

↳ 继承 Vehicle 的所有成员
doors: int (新增)

第二部分:super 关键字详解

掌握 super 的 3 种核心用法

1

调用父类构造方法

使用 super() 调用父类构造方法,必须是子类构造方法的第一条语句。

public class Animal { private String name; public Animal(String name) { this.name = name; } } public class Dog extends Animal { private String breed; // 正确:super 必须是第一条语句 public Dog(String name, String breed) { super(name); // 调用父类构造方法 this.breed = breed; } }
2

访问父类成员变量

当子类与父类有同名变量时,使用 super 明确访问父类变量。

public class Parent { int value = 100; } public class Child extends Parent { int value = 200; public void printValues() { System.out.println("Child value: " + value); // 200 System.out.println("Parent value: " + super.value); // 100 } }
3

调用父类方法

在方法重写时,使用 super 调用父类的实现。

public class Vehicle { public void start() { System.out.println("Vehicle starting with basic engine"); } } public class ElectricCar extends Vehicle { @Override public void start() { super.start(); // 先调用父类实现 System.out.println("Electric motor activated"); } }

第三部分:方法重写与继承链

掌握 @Override 注解和多级继承

1

方法重写规则

  • 方法名、参数列表必须相同
  • 访问权限不能比父类更严格
  • 返回类型可以是父类返回类型的子类型(协变返回类型)
  • 抛出的异常不能比父类更多
public class Animal { protected String getSound() { return "generic animal sound"; } } public class Cat extends Animal { @Override // 推荐添加此注解 public String getSound() { // 访问权限扩大 return "meow"; } }
2

多级继承示例

class GrandParent { void method1() { System.out.println("GrandParent method1"); } } class Parent extends GrandParent { void method2() { System.out.println("Parent method2"); } } class Child extends Parent { void method3() { System.out.println("Child method3"); } } // 使用示例 Child child = new Child(); child.method1(); // 继承自 GrandParent child.method2(); // 继承自 Parent child.method3(); // 自己的方法

第四部分:构造方法调用链

理解构造方法的自动调用机制

1

默认构造调用

如果子类构造方法没有显式调用 super(),编译器会自动插入 super()。

class A { A() { System.out.println("A constructor"); } } class B extends A { // 等价于:B() { super(); } B() { System.out.println("B constructor"); } } // 输出顺序:A constructor → B constructor
2

带参数的构造调用

class Person { String name; Person(String name) { this.name = name; System.out.println("Person created: " + name); } } class Employee extends Person { double salary; Employee(String name, double salary) { super(name); // 必须第一行 this.salary = salary; } }

第五部分:常见错误与调试

总结继承中最容易犯的错误

错误1:super 不在首行

class Parent { Parent(String name) {} } class Child extends Parent { Child() { int x = 10; // 错误:super 不是第一行 super("test"); } }

super() 必须是构造方法中的第一条语句

错误2:私有成员不可继承

class Parent { private int secret = 42; } class Child extends Parent { void accessSecret() { // System.out.println(secret); // 编译错误! // 正确做法:通过公共方法访问 } }

错误3:方法签名不匹配

class Parent { public void test(int x) {} } class Child extends Parent { // 这不是重写,而是重载! public void test(String x) {} }

第六部分:完整实战案例

通过银行系统演示继承的正确使用

1

基础类设计

// 基类:银行账户 public abstract class BankAccount { private String accountNumber; protected double balance; public BankAccount(String accountNumber, double initialBalance) { this.accountNumber = accountNumber; this.balance = initialBalance; } public void deposit(double amount) { balance += amount; } public abstract boolean withdraw(double amount); public String getAccountInfo() { return "Account: " + accountNumber + ", Balance: " + balance; } }
2

具体实现类

// 储蓄账户 public class SavingsAccount extends BankAccount { private double interestRate; public SavingsAccount(String accountNumber, double balance, double interestRate) { super(accountNumber, balance); // 调用父类构造 this.interestRate = interestRate; } @Override public boolean withdraw(double amount) { if (amount <= balance) { balance -= amount; return true; } return false; } public void applyInterest() { double interest = balance * interestRate / 100; super.deposit(interest); // 使用父类方法 } }
3

测试使用

public class BankTest { public static void main(String[] args) { SavingsAccount account = new SavingsAccount("SA001", 1000.0, 5.0); System.out.println(account.getAccountInfo()); account.deposit(500); account.applyInterest(); account.withdraw(200); System.out.println(account.getAccountInfo()); } }

第七部分:总结与最佳实践

继承使用的黄金法则

使用原则

  • 使用继承表示"is-a"关系
  • 子类应该能替代父类使用(里氏替换原则)
  • 避免过深的继承层次(不超过3层)
  • 优先使用组合而非继承

super 使用技巧

  • 总是显式调用父类构造方法
  • 使用 @Override 注解标记重写方法
  • 在重写方法中先调用 super 保留父类行为
  • 避免在构造方法中调用可重写的方法

综合练习

  1. 创建一个 Person → Employee → Manager 的继承层次
  2. 实现方法重写,展示多态行为
  3. 使用 super 调用父类构造和方法
  4. 添加异常处理和输入验证

学习建议

记住继承的核心是代码复用和多态。设计时先考虑"is-a"关系是否合理,再决定是否使用继承。调试时可以利用 IDE 的调试器逐步查看构造方法的调用顺序。