继承、多态与接口
继承、多态与接口
**继承(Inheritance)**是面向对象的核心机制之一,允许一个新类复用另一个类的属性和方法。**多态(Polymorphism)**则让同一操作作用于不同对象时产生不同的行为结果。**接口(Interface)**定义了行为的契约,是 Java 实现多态和解耦的重要工具。本文将深入讲解这三者的概念和使用方法。
继承的概念
继承允许在已有类的基础上创建新类,新类(子类)自动拥有父类的成员(属性和方法),同时可以添加自己特有的内容。
// 父类(基类 / 超类)
public class Animal {
protected String name; // protected:子类可访问
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name + " 正在吃东西...");
}
public void sleep() {
System.out.println(name + " 正在睡觉。");
}
}// 子类通过 extends 关键字继承父类
public class Dog extends Animal {
private String breed; // 子类独有的属性
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类构造器(必须在第一行)
this.breed = breed;
}
// 子类新增方法
public void bark() {
System.out.println(name + " 汪汪叫!");
}
// 子类重写父类方法
@Override
public void eat() {
System.out.println(name + "(" + breed + ")正在吃狗粮...");
}
}Dog dog = new Dog("旺财", 3, "金毛");
dog.eat(); // 旺财(金毛)正在吃狗粮... (重写后的版本)
dog.sleep(); // 旺财 正在睡觉。 (继承自父类)
dog.bark(); // 旺财 汪汪叫! (子类新增)Java 的单继承限制:Java 中类只能继承一个父类,不能同时继承多个类(与 C++ 的多重继承不同)。但一个类可以实现多个接口。
super 关键字
super 用于在子类中访问父类的成员——调用父类构造器或父类方法:
public class Cat extends Animal {
private boolean indoorCat;
public Cat(String name, int age, boolean indoorCat) {
super(name, age); // 调用父类构造器
this.indoorCat = indoorCat;
}
public void meow() {
System.out.println(name + " 喵喵叫~");
}
@Override
public void eat() {
super.eat(); // 先调用父类方法
System.out.println(name + " 吃完后舔了舔爪子。");
}
}方法重写(@Override)
子类可以**重写(Override)**父类的方法,用自己的实现替代父类的实现。@Override 注解是可选的,但强烈推荐使用——它让编译器帮你检查是否真的覆写了父类方法:
public class Bird extends Animal {
public Bird(String name, int age) {
super(name, age);
}
@Override // 加上注解,编译器检查方法签名是否正确
public void eat() {
System.out.println(name + " 用喙啄食...");
}
// 新增:飞翔方法
public void fly() {
System.out.println(name + " 在天空中飞翔!");
}
}重写规则
- 方法名、参数列表必须与父类完全相同
- 返回类型可以是可以是父类返回类型的子类(协变返回类型)
- 访问修饰符不能比父类更严格(父类
public→ 子类不能private) - 不能重写
static方法(隐藏,不是重写) - 不能重写
final方法
多态
多态指同一类型的引用,在指向不同类型的对象时,调用相同方法产生不同行为。多态是 OOP 的核心优势,让代码更具灵活性和可扩展性。
父类引用指向子类对象
// 父类类型引用可以指向子类对象(向上转型,自动转换)
Animal a1 = new Dog("旺财", 3, "金毛");
Animal a2 = new Cat("小咪", 2, true);
Animal a3 = new Bird("小鹦", 1);
// 调用 eat(),实际执行的是各个子类重写后的版本
a1.eat(); // 旺财(金毛)正在吃狗粮...
a2.eat(); // 喵喵叫~ ...吃完后舔了舔爪子。
a3.eat(); // 小鹦 用喙啄食...多态的条件
多态的发生需要满足三个条件:
- 存在继承关系——子类继承父类
- 子类重写父类方法——不同子类提供不同实现
- 父类引用指向子类对象——通过父类类型调用方法
// 多态数组:统一管理不同子类对象
Animal[] animals = {
new Dog("旺财", 3, "金毛"),
new Cat("小咪", 2, true),
new Bird("小鹦", 1)
};
for (Animal animal : animals) {
animal.eat(); // 每个对象调用自己的 eat() 实现
}
// 输出:
// 旺财(金毛)正在吃狗粮...
// 小咪 喵喵叫~
// 小鹦 用喙啄食...向下转型与 instanceof
父类引用默认只能调用父类中声明的方法。如果需要调用子类特有的方法,需要进行向下转型(强制转换),并用 instanceof 做类型检查:
Animal animal = new Dog("旺财", 3, "金毛");
// animal.bark(); // 编译错误:Animal 类没有 bark() 方法
// 向下转型:先检查类型,再转换
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // 强制转换为 Dog
dog.bark(); // 旺财 汪汪叫!
}
// Java 16+ 支持带变量的 instanceof 模式匹配
if (animal instanceof Dog dog) {
dog.bark(); // 直接使用 dog 变量,无需单独转型
}接口
接口(Interface)是一种完全抽象的类型,只定义方法签名(不提供实现),由具体类去实现。接口是 Java 实现多重继承的主要手段——一个类可以实现多个接口。
定义接口
// 定义接口
public interface Swimmable {
// 接口中的方法默认 public abstract(抽象方法)
void swim();
// Java 8+ 支持默认方法
default void floatOnWater() {
System.out.println("在水面上漂浮...");
}
}
public interface Flyable {
void fly();
}实现接口
// 实现接口使用 implements 关键字
// 一个类可以实现多个接口(多重继承)
public class Duck extends Animal implements Swimmable, Flyable {
public Duck(String name, int age) {
super(name, age);
}
@Override
public void swim() {
System.out.println(name + " 在湖里游泳!");
}
@Override
public void fly() {
System.out.println(name + " 在天空中飞行!");
}
}接口的默认方法与静态方法
Java 8 为接口引入了默认方法(default)和静态方法(static):
public interface Calculable {
int calculate(int x, int y);
// 默认方法:有默认实现,实现类可以直接使用或重写
default int square(int x) {
return x * x;
}
// 静态方法:属于接口本身,通过接口名调用
static int triple(int x) {
return x * 3;
}
}
public class BasicCalculator implements Calculable {
@Override
public int calculate(int x, int y) {
return x + y; // 实现 calculate 方法
}
}BasicCalculator calc = new BasicCalculator();
System.out.println(calc.calculate(3, 5)); // 8(使用实现的方法)
System.out.println(calc.square(4)); // 16(使用默认方法)
System.out.println(Calculable.triple(4)); // 12(使用静态方法)接口与抽象类的区别
| 特性 | 接口 | 抽象类 |
|---|---|---|
| 关键字 | interface | abstract class |
| 方法 | 抽象方法;Java 8+ 可有 default/static | 抽象方法 + 普通方法 |
| 变量 | 只能是 public static final 常量 | 可以有各种属性 |
| 继承/实现 | 类可以实现多个接口 | 类只能继承一个抽象类 |
| 构造器 | 不能有构造器 | 可以有构造器 |
| 适用场景 | 定义行为契约(“能做什么”) | 定义公共模板(“是什么”) |
常见 JDK 内置接口
// java.lang.Comparable:定义对象自然顺序
public class Student implements Comparable<Student> {
String name;
int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public int compareTo(Student other) {
return this.score - other.score; // 按分数升序排列
}
}
// Arrays.sort 使用 Comparable 接口排序
Student[] students = {
new Student("Alice", 92),
new Student("Bob", 78),
new Student("Carol", 85)
};
Arrays.sort(students);
for (Student s : students) {
System.out.println(s.name + ": " + s.score);
}
// Bob: 78
// Carol: 85
// Alice: 92完整示例:支付系统
用多态和接口构建一个灵活的支付系统:
// 支付接口
public interface PaymentMethod {
void pay(double amount);
String getName();
}
// 微信支付
public class WeChatPay implements PaymentMethod {
@Override
public void pay(double amount) {
System.out.println("使用微信支付 ¥" + String.format("%.2f", amount));
}
@Override
public String getName() {
return "微信支付";
}
}
// 支付宝
public class Alipay implements PaymentMethod {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付 ¥" + String.format("%.2f", amount));
}
@Override
public String getName() {
return "支付宝";
}
}
// 购物车结账
public class ShoppingCart {
private List<PaymentMethod> payments = new ArrayList<>();
public void addPayment(PaymentMethod payment) {
payments.add(payment);
}
public void checkout(double totalAmount) {
System.out.println("===== 订单总额:¥" + totalAmount + " =====");
for (PaymentMethod payment : payments) {
System.out.print(payment.getName() + " → ");
payment.pay(totalAmount);
}
}
}ShoppingCart cart = new ShoppingCart();
cart.addPayment(new WeChatPay());
cart.addPayment(new Alipay());
cart.checkout(299.99);
// ===== 订单总额:¥299.99 =====
// 微信支付 → 使用微信支付 ¥299.99
// 支付宝 → 使用支付宝支付 ¥299.99这个设计的优势:新增一种支付方式(如信用卡支付)只需新建一个类实现
PaymentMethod接口,无需修改ShoppingCart的代码(开闭原则)。
小结
- 继承通过
extends实现子类复用父类成员;Java 只支持单继承 - **方法重写(Override)**让子类提供父类方法的自定义实现;
@Override注解是最佳实践 - 多态通过父类引用指向子类对象,使同一调用产生不同行为;使用
instanceof做类型检查 - 接口定义行为契约,支持类实现多个接口;Java 8+ 支持 default 和 static 方法
- 抽象类 vs 接口:抽象类定义「是什么」的模板,接口定义「能做什么」的能力
继承、多态与接口是 Java 面向对象编程的三大支柱,理解它们才能写出结构清晰、易于扩展的代码。下一节我们将学习 Java 异常处理机制,掌握如何优雅地管理程序运行中的错误。
评论
Written by
AI-Writer
Related Articles
后端开发工具链:构建、测试与日志
快速上手 Maven(pom.xml、依赖管理、生命周期)和 Gradle,构建自动化项目;掌握 JUnit 5 单元测试基础和 SLF4J + Logback 日志框架
Read MoreJava 17+ 新特性精讲
全面讲解 Java 17 LTS 的核心新特性:Records、Sealed Classes、Pattern Matching for instanceof、Text Blocks、Switch Expressions,附详细代码示例
Read More