| 学习指南 EN
AP · Inheritance / 继承 · 阅读约 15 分钟 · 更新于 2026-05-07

继承 (Inheritance) — AP Computer Science A CS A 学习指南

适合谁:AP Computer Science A 参加 AP Computer Science A 的考生。

覆盖内容:超类与子类定义、extends与super关键字用法、方法重写与@Override注解规则、多态IS-A关系、抽象类入门核心考点

前置知识:基础 Java 或任何其他过程式语言编程。

关于练习题:下文「练习题」一节的所有题目均为我们按 AP Computer Science A 风格编写的原创题目 (original problems),仅用于教学。它们不是 College Board 真题的复制,措辞、数值或语境可能不同。请把它们当作练手用;评分细则请对照 College Board 官方 mark scheme。


1. 什么是继承?

继承(Inheritance)是面向对象编程中实现代码复用的核心机制,允许新建的类吸收已有类的属性、方法,同时扩展自定义的功能,避免重复编写相同逻辑。本章节对应AP CS A CED第9单元,占考试总分约8%-10%,选择题和自由作答(FRQ)均会出题,是面向对象模块的核心考点。 继承的核心价值是实现类的层次化设计,符合现实世界的分类逻辑,比如「学生是人的一种」「狗是动物的一种」,无需在每个细分分类中重复定义通用属性。

2. 超类(Superclass)与子类(Subclass)

被继承的类称为超类(Superclass,也叫父类),继承超类的新类称为子类(Subclass,也叫派生类)。 子类可以直接访问超类的publicprotected成员(属性、方法),但无法直接访问超类的private成员,必须通过超类提供的公开方法间接访问。

范例

// 超类:定义通用属性和方法
public class Person {
 private String name;
 private int age;
 public Person(String n, int a) { name = n; age = a; }
 public void greet() { System.out.println("你好,我是" + name); }
}
// 子类:继承Person,扩展独有属性studentId和方法study
public class Student extends Person {
 private String studentId;
 public void study() { System.out.println("正在学习AP CS A"); }
}

上述代码中Student IS-A Person,自动拥有greet()方法,无需重复编写。

3. extends关键字与super调用

extends是Java中声明继承关系的关键字,语法为class 子类名 extends 超类名。注意Java仅支持单继承,一个子类最多只能继承一个超类,这是AP选择题的高频考点。 super关键字有两个核心用法:

  1. 调用超类构造方法:必须放在子类构造方法的第一行。如果子类构造没有显式写super调用,编译器会自动添加无参的super();如果超类没有无参构造方法,会直接编译报错。
  2. 调用超类的普通成员:当子类重写了超类方法后,可以用super.方法名()调用超类的原实现,也可以用super.属性名访问超类的非私有属性。

范例

public class Student extends Person {
 private String studentId;
 public Student(String n, int a, String id) {
 super(n, a); // 第一行调用超类有参构造,初始化name和age
 studentId = id;
 }
 @Override
 public void greet() {
 super.greet(); // 调用超类的greet实现
 System.out.println("我的学号是" + studentId);
 }
}

4. 方法重写(Method Overriding)与@Override

方法重写指子类定义和超类方法签名完全相同(方法名、参数列表、返回值类型一致)的方法,覆盖超类的原有实现,是实现多态的前提。 @Override是Java提供的注解,加在重写方法上方后,编译器会自动检查该方法是否符合重写规则,如果拼写错误、参数列表不匹配会直接报错,避免逻辑bug,AP考试中建议所有重写方法都添加该注解。 重写的核心规则:

  • 访问修饰符不能比超类方法更严格(比如超类是public,子类不能用protected
  • 不能抛出比超类方法更宽泛的受检异常 ⚠️ 注意和方法重载(Overload)区分:重载是同一个类中方法名相同、参数列表不同,和重写没有关系,不能加@Override注解,这是高频丢分点。

5. 多态(Polymorphism)与IS-A关系

继承天然存在IS-A关系,比如Student IS-A Person,多态就是基于IS-A关系实现的特性:超类类型的引用可以指向子类类型的对象,调用同一个方法时,实际执行的逻辑取决于引用指向的实际对象类型,这个机制叫做动态绑定(Dynamic Binding),是AP必考考点。

范例

Person p1 = new Person("张三", 18);
Person p2 = new Student("李四", 17, "2024001");
p1.greet(); // 执行Person类的greet方法
p2.greet(); // 执行Student类重写后的greet方法

⚠️ 注意:编译阶段只会检查引用的编译类型(上述例子中是Person)有没有对应方法,要调用子类独有的方法(比如study()),必须先强制类型转换为子类类型:((Student)p2).study();

6. 抽象类(Abstract Classes)入门

抽象类是用abstract关键字修饰的类,核心规则如下:

  1. 不能被实例化(不能用new直接创建抽象类的对象)
  2. 可以包含抽象方法:用abstract修饰、只有方法签名没有实现的方法,比如public abstract double getArea();
  3. 继承抽象类的非抽象子类,必须实现抽象类中所有的抽象方法,否则该子类也要声明为抽象类
  4. 抽象类也可以包含普通实现的方法、属性、构造方法,并非只能有抽象方法 抽象类通常用来定义类层次的通用模板,把公共逻辑写在抽象类中,把需要子类个性化实现的逻辑定义为抽象方法,强制子类实现。

7. 常见陷阱(Common Pitfalls)

  1. 错误做法:超类只有有参构造方法,子类构造没有显式调用super(参数),导致编译报错。 原因:误以为编译器会自动匹配参数调用超类有参构造,实际默认只会加无参super()。 正确做法:如果超类没有无参构造,子类构造第一行必须显式调用super(参数)匹配超类的有参构造。
  2. 错误做法:把方法重载当成重写,添加@Override后编译报错。 原因:分不清重写要求方法签名完全相同,重载仅要求方法名相同、参数不同。 正确做法:只有方法名、参数列表、返回值都和超类完全一致时才是重写,才能加@Override
  3. 错误做法:超类引用指向子类对象时,直接调用子类独有的方法,编译报错。 原因:以为运行类型是子类就能调用子类所有方法,实际编译阶段只检查引用的编译类型。 正确做法:调用子类独有方法前先做强制类型转换,确保类型匹配。
  4. 错误做法:重写方法时使用比超类更严格的访问修饰符,比如超类是public,子类写成protected。 原因:不知道重写的访问权限规则,重写是为了替代超类方法,不能缩小可访问范围。 正确做法:重写方法的访问修饰符必须和超类相同或更宽松(public > protected > 包访问 > private)。

8. 练习题(AP CS A风格)

题1(选择题)

现有代码如下:

class Animal {
 public void makeSound() { System.out.print("普通叫声"); }
}
class Cat extends Animal {
 @Override
 public void makeSound() { System.out.print("喵"); }
 public void scratch() { System.out.print("挠沙发"); }
}

执行代码Animal a = new Cat(); a.makeSound();的输出结果是? A. 普通叫声 B. 喵 C. 编译错误 D. 运行异常 解答:选B。动态绑定机制下,方法调用看实际运行类型是Cat,执行重写后的makeSound方法。如果调用a.scratch()会编译错误,因为Animal类没有scratch方法。

题2(改错题)

下列代码有几处编译错误?请说明原因。

abstract class Shape {
 private String color;
 public Shape(String c) { color = c; }
 public abstract double getArea();
}
class Circle extends Shape {
 private double radius;
 public Circle(String c, double r) { radius = r; }
 public double getArea() { return Math.PI * radius * radius; }
}

解答:1处错误Circle的构造方法没有显式调用超类Shape的有参构造,超类没有无参构造,编译器自动添加的super()无法匹配,应该在构造第一行添加super(c);

题3(FRQ风格代码题)

请编写一个子类Square继承上述Shape抽象类,包含私有属性side(边长),构造方法接收颜色和边长两个参数,实现getArea方法返回正方形面积。 解答:

public class Square extends Shape {
 private double side;
 public Square(String color, double side) {
 super(color);
 this.side = side;
 }
 @Override
 public double getArea() {
 return side * side;
 }
}

9. 速查表(Quick Reference Cheatsheet)

知识点 核心规则
extends关键字 Java单继承,一个子类最多继承一个超类
super构造调用 必须放在子类构造第一行,无显式调用时编译器自动加无参super()
方法重写 方法签名完全相同,访问权限不低于超类,建议加@Override注解
动态绑定 方法调用看运行时实际对象类型,属性访问看编译时引用类型
抽象类 abstract修饰,不能实例化,非抽象子类必须实现所有抽象方法

10. 接下来怎么学

继承是AP CS A面向对象模块的核心基础,后续要学习的接口(Interface)、多态进阶、类层次设计考点都建立在本章的IS-A关系、方法重写、动态绑定规则之上,本章知识点在FRQ中常和数组、ArrayList结合出题,需要你熟练掌握规则并灵活应用。 如果你在做继承相关真题时遇到任何疑问,都可以随时到小欧提问,我们会给你提供针对性的讲解和练习巩固。

← 返回章节主页

某道题卡住了?
拍照或粘贴题目 — 小欧(我们的 AI 学习助手)会一步步讲解并配示意图。
免费试用小欧 →