Java程序:类的复用与继承全解析,附开发避坑指南
```java // 引擎类,作为组合的一部分 class Engine { private String engineType; public Engine(String engineType) { this.engineType = engineType; System.out.println("引擎已安装: " + engineType); } public void start() { System.out.println(engineType + "引擎启动"); } public void stop() { System.out.println(engineType + "引擎关闭"); } } // 车辆类,使用组合方式包含引擎 class Vehicle { private String brand; private Engine engine; // 组合:Vehicle 拥有 Engine public Vehicle(String brand, String engineType) { this.brand = brand; this.engine = new Engine(engineType); System.out.println("车辆品牌: " + brand + " 创建完成"); } public void start() { System.out.println(brand + "车辆开始启动流程..."); engine.start(); // 复用 Engine 的功能 } public void stop() { engine.stop(); System.out.println(brand + "车辆已停止"); } } // 军舰父类,用于继承演示 class Warship { protected String name; protected int weaponCount; // 无参构造 public Warship() { System.out.println("Warship 无参构造方法被调用"); } // 有参构造 public Warship(String name, int weaponCount) { this.name = name; this.weaponCount = weaponCount; System.out.println("Warship 有参构造方法被调用: " + name); } // 普通方法 public void sail() { System.out.println(name + " 正在航行"); } // 可被重写的方法 public void attack() { System.out.println(name + " 使用 " + weaponCount + " 门火炮进行攻击"); } // 重写 toString 方法 @Override public String toString() { return "Warship{" + "name='" + name + '\'' + ", weaponCount=" + weaponCount + '}'; } // 重写 equals 方法进行比较 @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Warship)) return false; Warship other = (Warship) obj; return weaponCount == other.weaponCount && name.equals(other.name); } } // 护卫舰类,继承自 Warship final class Frigate extends Warship { // final 类,不可再被继承 private String escortMission; // final 方法,不可被重写 public final void performEscort() { System.out.println(name + " 正在执行护航任务: " + escortMission); } // 构造方法1:默认 public Frigate() { super(); // 调用父类无参构造 System.out.println("Frigate 无参构造方法被调用"); } // 构造方法2:带参 public Frigate(String name, int weaponCount, String mission) { super(name, weaponCount); // 调用父类有参构造 this.escortMission = mission; System.out.println("Frigate 有参构造方法被调用: " + name); } // 重写父类的 attack 方法 @Override public void attack() { super.attack(); // 使用 super 调用父类方法 System.out.println(name + " 同时发射导弹支援!"); } // 重写 toString 方法以提供更详细的信息 @Override public String toString() { return "Frigate{" + "name='" + name + '\'' + ", weaponCount=" + weaponCount + ", escortMission='" + escortMission + '\'' + '}'; } } // 演示类 public class InheritanceAndCompositionDemo { public static void main(String[] args) { System.out.println("=== 组合演示:Vehicle 和 Engine ==="); Vehicle car = new Vehicle("丰田", "V6"); car.start(); System.out.println(); System.out.println("=== 继承演示:Warship 和 Frigate ==="); Frigate frigate = new Frigate("护卫舰054A", 32, "南海巡逻"); frigate.sail(); frigate.attack(); // 会调用 super.attack() frigate.performEscort(); System.out.println("\n--- toString 演示 ---"); System.out.println(frigate.toString()); System.out.println("\n--- equals 演示 ---"); Warship ship1 = new Warship("护卫舰054A", 32); Warship ship2 = new Warship("护卫舰054A", 32); System.out.println("ship1 和 ship2 是否相等: " + ship1.equals(ship2)); // final 成员变量演示 final double MAX_SPEED = 30.5; System.out.println("最大航速限制: " + MAX_SPEED + " 节"); // MAX_SPEED = 35; // 编译错误:不能修改 final 变量 } } ``` 说明: 1)组合与继承 - `Vehicle` 类通过组合方式持有 `Engine` 对象,体现“有一个”关系。 - `Frigate` 类继承 `Warship`,体现“是一个”关系。 2)方法重写与 super 关键字 - `Frigate` 重写了 `attack()` 方法,在增强原有行为的通过 `super.attack()` 保留父类逻辑。 - `super` 用于调用父类被覆盖的方法或构造函数。 3)构造方法调用顺序 - 创建 `Frigate` 实例时,先调用 `Warship` 的构造方法(父类),再执行子类构造体,体现“先父后子”。 4)Object 类的应用 - 重写 `toString()` 提供对象的可读字符串表示。 - 重写 `equals()` 实现基于内容的比较,而非默认的引用比较。 5)final 关键字使用 - `Frigate` 类被声明为 `final`,防止被其他类继承,确保安全性和设计完整性。 - `performEscort()` 方法为 `final`,防止子类篡改核心行为(尽管此类已是 final)。 - 局部变量 `MAX_SPEED` 为 `final`,表示常量值不可更改。 我在以往的开发过程中,碰到过以下几点需要格外小心处理的地方: - 继承层次过深会导致维护困难,优先考虑组合而非继承 - 忘记调用 super 相关方法可能导致父类初始化失败或逻辑缺失 - 重写 equals 方法时未同时重写 hashCode 方法,会导致集合类中行为异常 ######[AI写代码神器 | 1509点数解答 | 2025-11-07 16:31:52]
- Java 实现复制粘贴功能:打造简易文本复制粘贴程序(GPT | 1497点数解答 | 2024-08-25 09:40:33)413
- 解决数据库“dm.jdbc.driver.dmexception: 数据溢出”问题的全步骤指南(阿里通义 | 598点数解答 | 2024-10-15 15:48:38)314
- 达梦数据库数据溢出问题排查及多维度解决方法(阿里通义 | 403点数解答 | 2024-10-15 15:48:41)1167
- Golang开发:解析JSON数据时数值默认类型及示例解析(百度文心 | 393点数解答 | 2023-11-09 18:13:06)284
- SQL Working Areas Sizing: Manual vs. Automatic Policy - A Comprehensive Analysis(阿里通义 | 530点数解答 | 2024-05-13 10:55:58)312
- Java 实现交通工具类继承:从 Vehicles 到 Car 的完整示例(字节豆包 | 289点数解答 | 2024-09-18 16:16:54)242
- "Java Code: Uncovering Stock Statistics through CSV File Reading"(字节豆包 | 66点数解答 | 2024-11-13 15:31:04)324
- C++ 实战:交通工具基类与小汽车类的继承实现及测试(字节豆包 | 391点数解答 | 2024-09-18 16:16:39)267
- Java 实战:手机类继承与方法重写实现打电话功能(字节豆包 | 297点数解答 | 2024-09-19 17:22:13)240
- JavaScript:用类与继承实现 Dog 类输出“woof”(阿里通义 | 302点数解答 | 2024-10-29 10:14:24)417
- JavaScript 运用类与继承:实现 Dog 类重写 speak 方法输出“woof”(字节豆包 | 191点数解答 | 2024-10-29 21:08:03)214
- Java 实战:汽车类继承车辆基类,实现属性扩展与方法重写(字节豆包 | 220点数解答 | 2025-04-15 14:38:26)303