【从零开始学习JAVA | 第四篇】继承与多态

【从零开始学习JAVA | 第四篇】继承与多态 前言上一篇我们掌握了面向对象的基础——类与对象、封装。本篇继续深入学习面向对象三大特性中的另外两个继承和多态。这两个特性是 Java 实现代码复用、灵活扩展的核心机制也是面试中最高频的考点之一务必认真学习。一、继承1.1 什么是继承继承允许一个类获取另一个类的属性和方法避免重复代码。被继承的类叫父类超类继承的类叫子类使用关键字extendsgraph TD A[Animal 父类] -- B[Dog 子类] A -- C[Cat 子类] A -- D[Bird 子类] style A fill:#cce5ff style B fill:#d4edda style C fill:#d4edda style D fill:#d4edda 生活类比父亲有房子和车儿子继承后直接拥有不需要自己再买。1.2 继承的基本写法不使用继承时存在大量重复代码// 重复定义相同属性和方法 ❌ public class Dog { String name; int age; public void eat() { System.out.println(name 在吃饭); } public void bark() { System.out.println(汪汪汪); } } public class Cat { String name; int age; public void eat() { System.out.println(name 在吃饭); } public void meow() { System.out.println(喵喵喵); } }使用继承后公共部分抽取到父类// 父类 public class Animal { String name; int age; public void eat() { System.out.println(name 在吃饭); } } // 子类 Dog public class Dog extends Animal { public void bark() { System.out.println(name 说汪汪汪); } } // 子类 Cat public class Cat extends Animal { public void meow() { System.out.println(name 说喵喵喵); } }public class Demo { public static void main(String[] args) { Dog dog new Dog(); dog.name 旺财; dog.age 3; dog.eat(); // 继承自父类 dog.bark(); // 自己的方法 Cat cat new Cat(); cat.name 咪咪; cat.eat(); cat.meow(); } }输出结果旺财 在吃饭 旺财 说汪汪汪 咪咪 在吃饭 咪咪 说喵喵喵1.3 继承的特点Java 只支持单继承一个类只能有一个直接父类但支持多层继承A → B → C所有类默认继承Object类Java 的祖宗类graph TD A[Object] -- B[Animal] B -- C[Dog] C -- D[导盲犬 GuideDoc] style A fill:#ffe0cc style B fill:#cce5ff style C fill:#d4edda style D fill:#fff3cd1.4 子类能继承什么父类成员能否继承public 属性/方法✅ 可以protected 属性/方法✅ 可以默认(不写修饰符)✅ 同包可以private 属性/方法❌ 不能直接访问构造方法❌ 不能继承但可以调用二、super 关键字super代表父类对象用于访问父类的属性、方法和构造方法。2.1 调用父类构造方法public class Animal { private String name; private int age; public Animal(String name, int age) { this.name name; this.age age; } public String getName() { return name; } }public class Dog extends Animal { private String breed; // 品种 public Dog(String name, int age, String breed) { super(name, age); // 必须在第一行调用父类构造 this.breed breed; } public void printInfo() { System.out.println(名字 getName() 品种 breed); } }Dog dog new Dog(旺财, 3, 拉布拉多); dog.printInfo(); // 名字旺财品种拉布拉多2.2 this 与 super 对比thissuper代表当前对象父类对象访问属性this.属性super.属性调用方法this.方法()super.方法()调用构造this()super()位置要求构造方法第一行构造方法第一行⚠️this()和super()不能同时出现在构造方法中。三、方法重写Override方法重写子类对父类继承来的方法进行重新定义覆盖原有实现。3.1 重写规则方法名、参数列表必须完全相同返回值类型相同或是其子类访问权限不能更严格可以更宽松建议加Override注解让编译器帮助检查public class Animal { public void speak() { System.out.println(动物在叫...); } } public class Dog extends Animal { Override public void speak() { System.out.println(汪汪汪); } } public class Cat extends Animal { Override public void speak() { System.out.println(喵喵喵); } }public class Demo { public static void main(String[] args) { Animal a new Animal(); Dog d new Dog(); Cat c new Cat(); a.speak(); // 动物在叫... d.speak(); // 汪汪汪 c.speak(); // 喵喵喵 } }3.2 重写 vs 重载方法重载Overload方法重写Override位置同一个类父子类之间方法名相同相同参数列表必须不同必须相同返回值无要求必须相同或子类四、多态4.1 什么是多态多态同一种行为不同对象表现出不同的形态。核心口诀父类引用指向子类对象Animal a new Dog(); // 父类类型的变量指向子类对象graph LR A[Animal类型的引用] --|指向| B[Dog对象] A --|指向| C[Cat对象] A --|指向| D[Bird对象] style A fill:#cce5ff4.2 多态的完整示例public class Animal { private String name; public Animal(String name) { this.name name; } public String getName() { return name; } public void speak() { System.out.println(动物在叫); } } public class Dog extends Animal { public Dog(String name) { super(name); } Override public void speak() { System.out.println(getName() 说汪汪汪); } } public class Cat extends Animal { public Cat(String name) { super(name); } Override public void speak() { System.out.println(getName() 说喵喵喵); } }public class Demo { public static void main(String[] args) { // 父类引用指向不同子类对象 Animal a1 new Dog(旺财); Animal a2 new Cat(咪咪); Animal a3 new Dog(小黑); // 同一方法不同表现 a1.speak(); a2.speak(); a3.speak(); } }输出结果旺财 说汪汪汪 咪咪 说喵喵喵 小黑 说汪汪汪4.3 多态的最大好处多态让方法可以接收任意子类对象极大提升代码灵活性public class Demo { // 只需写一个方法传入任何 Animal 子类都能正确执行 public static void letSpeak(Animal animal) { animal.speak(); } public static void main(String[] args) { letSpeak(new Dog(旺财)); letSpeak(new Cat(咪咪)); } } 以后新增Bird类letSpeak方法无需改动直接传入即可。这就是多态的威力。4.4 多态的弊端与类型转换使用父类引用时只能调用父类中定义的方法无法调用子类独有方法。Animal a new Dog(旺财); a.speak(); // ✅ 可以Animal 中有 speak a.bark(); // ❌ 报错Animal 中没有 bark需要调用子类独有方法时要进行向下转型Animal a new Dog(旺财); // 向下转型前先用 instanceof 判断类型 if (a instanceof Dog) { Dog d (Dog) a; // 强制转换 d.bark(); // ✅ 现在可以调用了 }graph TD A[向上转型] --|自动, 安全| B[Animal a new Dog()] C[向下转型] --|强制, 需判断| D[Dog d (Dog) a] D -- E{instanceof 检查} E --|是 Dog| F[✅ 转换成功] E --|不是 Dog| G[❌ ClassCastException] style F fill:#d4edda style G fill:#f8d7da五、final 关键字final表示最终的、不可改变的可以修饰类、方法、变量。修饰对象含义final类不能被继承如 String 类final方法不能被重写final变量变为常量不能重新赋值// final 类不能被继承 public final class MathUtil { } public class Animal { // final 方法不能被重写 public final void breathe() { System.out.println(呼吸); } } public class Demo { public static void main(String[] args) { // final 变量相当于常量 final double PI 3.14159; // PI 3.14; // ❌ 报错不能修改 System.out.println(PI); } }六、综合练习题目定义员工体系公司有普通员工和经理都有姓名和工资但经理还有奖金且工作内容不同。// 父类 public class Employee { private String name; private double salary; public Employee(String name, double salary) { this.name name; this.salary salary; } public String getName() { return name; } public double getSalary() { return salary; } public void work() { System.out.println(name 正在工作); } public void printSalary() { System.out.println(name 的薪资¥ salary); } }// 普通员工 public class Worker extends Employee { public Worker(String name, double salary) { super(name, salary); } Override public void work() { System.out.println(getName() 正在努力搬砖 ); } }// 经理 public class Manager extends Employee { private double bonus; public Manager(String name, double salary, double bonus) { super(name, salary); this.bonus bonus; } Override public void work() { System.out.println(getName() 正在开会讨论方案 ); } Override public void printSalary() { System.out.println(getName() 的薪资¥ getSalary() 奖金¥ bonus); } }public class Demo { public static void main(String[] args) { Employee[] staff { new Worker(小明, 8000), new Worker(小红, 9000), new Manager(王总, 20000, 50000) }; for (Employee e : staff) { e.work(); e.printSalary(); System.out.println(------); } } }输出结果小明 正在努力搬砖 小明 的薪资¥8000.0 ------ 小红 正在努力搬砖 小红 的薪资¥9000.0 ------ 王总 正在开会讨论方案 王总 的薪资¥20000.0奖金¥50000.0 ------总结graph TD A[继承与多态] -- B[继承 extends] A -- C[多态] B -- B1[代码复用] B -- B2[super关键字] B -- B3[方法重写 Override] C -- C1[父类引用指向子类对象] C -- C2[向上转型 - 自动] C -- C3[向下转型 - 强制instanceof] C -- C4[多态的好处: 统一处理不同子类] A -- D[final关键字] D -- D1[final类不能继承] D -- D2[final方法不能重写] D -- D3[final变量是常量]知识点核心要点继承extends子类拥有父类非private成员super代表父类调用父类构造必须在第一行方法重写方法名参数相同子类覆盖父类实现多态父类引用指向子类对象运行时动态绑定类型转换向上自动向下强转转前用instanceof判断final修饰类/方法/变量表示不可变写在最后本篇是「从零开始学习JAVA」系列的第四篇完整介绍了继承与多态的核心概念和实际应用。继承减少了重复代码多态让程序更灵活、更易扩展二者结合是 Java 面向对象设计的精髓。建议把综合练习完整敲一遍感受多态带来的便利。如果觉得本文对你有帮助欢迎点赞 收藏 ⭐ 关注我们下一篇见下一篇预告【从零开始学习JAVA | 第五篇】抽象类与接口