Java 面向对象基础二作者没有四次元口袋的蓝胖日期2026-06-04标签Java, 面向对象, 继承, super, 重写, 多态一、继承1.1 什么是继承继承是子类复用父类属性和行为的机制体现“is-a”关系。classAnimal{Stringname;publicvoideat(){System.out.println(name在吃东西);}}classDogextendsAnimal{publicvoidbark(){System.out.println(name在汪汪叫);}}DogdnewDog();d.name旺财;d.eat();// 继承自 Animald.bark();// Dog 自己的1.2 继承的特点特点说明单继承一个类只能有一个直接父类Java 不支持多继承多层继承A → B → C可以形成继承链所有类根没有显式继承时默认继承java.lang.Object子类获得父类非 private 的属性和方法子类不可获父类的构造方法、private 成员1.3 继承中的访问权限子类能访问的父类成员 ✅ public → 哪里都能用 ✅ protected → 同包 不同包子类 ✅ 缺省(default) → 同包 ❌ private → 只有父类自己能用但可以通过 public/protected 的 getter 间接访问1.4 什么时候用继承is-a 关系才用继承has-a 关系用组合。✅ Dog is an Animal → 继承狗是动物 ✅ Cat is an Animal → 继承猫是动物 ❌ Car has a Wheel → 组合不是继承车有轮胎 ❌ Student has a Book → 组合不是继承学生有书你可以说 “狗是动物”、“猫是动物”但是不能说“车是轮胎”“学生是书”不然就会出现“给汽车充气”、“获取学生价格”这样不合逻辑的情况。二、super 关键字2.1 super 是什么super代表父类的引用用于在子类中访问父类的成员。2.2 三种用法用法 1访问父类成员变量当子类和父类有同名变量时用super区分classAnimal{Stringname动物;}classDogextendsAnimal{Stringname狗;publicvoidshow(){System.out.println(name);// 狗子类System.out.println(super.name);// 动物父类}}用法 2调用父类成员方法classAnimal{publicvoideat(){System.out.println(动物在吃东西);}}classDogextendsAnimal{Overridepublicvoideat(){super.eat();// 先调用父类版本System.out.println(狗在啃骨头);}}newDog().eat();// 动物在吃东西// 狗在啃骨头用法 3调用父类构造方法classAnimal{Stringname;publicAnimal(Stringname){this.namename;}}classDogextendsAnimal{Stringbreed;publicDog(Stringname,Stringbreed){super(name);// 调用父类构造必须放在第一行this.breedbreed;}}2.3 super vs this对比superthis代表父类引用当前对象引用访问成员super.变量/super.方法()this.变量/this.方法()调用构造super(...)在子类构造第一行this(...)在构造第一行互斥super()和this()不能同时出现在一个构造方法中同左2.4 子类构造的隐式 super()classAnimal{publicAnimal(){System.out.println(Animal 构造);}}classDogextendsAnimal{publicDog(){super();// 即使不写编译器也会自动加上System.out.println(Dog 构造);}}newDog();// Animal 构造// Dog 构造⚠️ 如果父类没有无参构造子类必须显式用super(...)调用父类有参构造否则编译报错。三、方法重写Override3.1 什么是重写子类对父类的方法重新实现使同一方法在不同子类中表现不同行为。3.2 重写规则规则说明方法名必须相同参数列表必须相同返回值类型相同或是父类返回值类型的子类协变返回访问权限不能比父类更严格可以更宽异常不能抛出比父类更多的受检异常private/static/final不能被重写权限放宽方向private→ 缺省 →protected→publicclassAnimal{publicObjectgetInfo(){return动物信息;}}classDogextendsAnimal{OverridepublicStringgetInfo(){return狗的信息;}// ✅ String 是 Object 的子类协变返回}3.3 Override 注解强烈建议每次重写都加上Override让编译器帮你检查classDogextendsAnimal{Overridepublicvoideat(){}// ✅ 正确重写Overridepublicvoideet(){}// ❌ 编译报错父类没有这个方法说明你拼错了}3.4 重写 vs 重载完整对比对比重载Overload重写Override发生位置同一个类子类与父类方法名相同相同参数列表必须不同必须相同返回值无关相同或子类访问权限无关不能更严格关系编译时多态运行时多态四、多态4.1 什么是多态同一个引用类型调用同一个方法表现出不同的行为。核心前提有继承 / 实现关系有方法重写父类引用指向子类对象4.2 基本用法classAnimal{publicvoidspeak(){System.out.println(动物叫);}}classDogextendsAnimal{Overridepublicvoidspeak(){System.out.println(汪汪汪);}}classCatextendsAnimal{Overridepublicvoidspeak(){System.out.println(喵喵喵);}}Animala1newDog();// 父类引用 → 子类对象向上转型Animala2newCat();a1.speak();// 汪汪汪 ← 运行时看实际对象类型a2.speak();// 喵喵喵 ← 运行时看实际对象类型编译看左边运行看右边——编译时检查引用类型有没有这个方法运行时执行实际对象的重写版本。4.3 向上转型与向下转型向上转型自动安全AnimalanewDog();// 子类 → 父类自动转型a.speak();// 汪汪汪多态生效// a.bark(); // ❌ 编译报错Animal 没有 bark()向上转型后只能调用父类中声明的方法不能调用子类特有的方法。向下转型强制需谨慎AnimalanewDog();Dogd(Dog)a;// 强制向下转型d.bark();// ✅ 现在可以调用了Catc(Cat)a;// ❌ 运行时 ClassCastExceptiona 实际是 Doginstanceof 判断安全转型的保障AnimalanewDog();if(ainstanceofDog){Dogd(Dog)a;d.bark();}elseif(ainstanceofCat){Catc(Cat)a;c.catchMouse();}4.4 多态的实际应用场景方法参数用父类类型兼容所有子类classOwner{publicvoidfeed(Animalanimal){// 任何 Animal 子类都能传animal.speak();System.out.println(喂食完成);}}OwnerownernewOwner();owner.feed(newDog());// 汪汪汪 → 喂食完成owner.feed(newCat());// 喵喵喵 → 喂食完成不用多态的话你要写feed(Dog d)、feed(Cat c)……每加一种动物就加一个方法。多态一个方法搞定。4.5 多态中成员变量没有多态效果classAnimal{Stringname动物;}classDogextendsAnimal{Stringname狗;}AnimalanewDog();System.out.println(a.name);// 动物 ← 成员变量看左边引用类型// 多态只对方法有效变量没有多态五、常见坑与面试考点坑 1父类没有无参构造子类编译报错classAnimal{publicAnimal(Stringname){}// 只有有参构造无参构造没了}classDogextendsAnimal{publicDog(){}// ❌ 编译报错隐式 super() 找不到无参构造publicDog(){super(默认);}// ✅ 显式调用父类有参构造}坑 2重写时缩小了访问权限classAnimal{publicvoideat(){}}classDogextendsAnimal{Overridevoideat(){}// ❌ 从 public 缩小到 default编译报错}坑 3类初始化顺序经典面试题classParent{static{System.out.println(1. 父类静态代码块);}{System.out.println(2. 父类实例代码块);}publicParent(){System.out.println(3. 父类构造方法);}}classChildextendsParent{static{System.out.println(4. 子类静态代码块);}{System.out.println(5. 子类实例代码块);}publicChild(){System.out.println(6. 子类构造方法);}}newChild();// 输出顺序1 → 4 → 2 → 3 → 5 → 6口诀父类静态 → 子类静态 → 父类实例/构造 → 子类实例/构造六、思维导图速览面向对象进阶二—— 继承与多态 ├── 继承 │ ├── is-a 关系单继承 │ ├── 子类获得父类非 private 成员 │ └── 所有类默认继承 Object ├── super 关键字 │ ├── 访问父类成员super.变量 / super.方法() │ ├── 调用父类构造super()必须在第一行 │ └── vs this 对比 ├── 方法重写Override │ ├── 规则方法名/参数相同权限不能更严 │ ├── Override 注解强烈建议 │ └── vs 重载Overload完整对比 └── 多态 ├── 编译看左边运行看右边 ├── 向上转型自动/ 向下转型强制 instanceof ├── 实际应用方法参数用父类类型 └── 成员变量没有多态效果写在最后多态是重中之重——理解编译看左、运行看右是打开 Java 面向对象大门的钥匙结合内存模型想几遍就通了。super 三种用法要熟练尤其是super()调用父类构造。重写 vs 重载现在就分清楚后面学泛型会更晕趁早搞明白。初始化顺序口诀记住面试手写一遍验证。