13 继承
目录 13 继承 目录13.1 为什么需要继承13.2 继承的语法13.2.1 基本语法13.2.2 示例人 → 老师/学生13.2.3 测试13.3 继承中成员变量的特点13.3.1 变量访问规则13.3.2 三种变量对比13.4 方法重写Override13.4.1 什么是方法重写13.4.2 重写的规则13.4.3 重写 vs 重载13.4.4 重写的应用13.5 super关键字13.5.1 super的用法13.5.2 示例13.6 继承中构造方法的特点13.6.1 子类构造方法会调用父类构造方法13.6.2 构造方法的执行顺序13.6.3 使用super(参数)调用父类有参构造13.7 Object类13.7.1 Object是什么13.7.2 Object的常用方法13.7.3 重写toString()13.7.4 重写equals()13.8 继承的注意事项13.8.1 Java只支持单继承13.8.2 继承的使用场景13.8.3 访问修饰符总结13.9 综合案例动物世界13.10 本章总结知识回顾练习题 互动时间 参考资料 13 继承更新日期2026年5月版权声明本文为原创内容转载请注明出处。系列Java入门到精通系列 · 第二阶段 · 面向对象 目录13.1 为什么需要继承13.2 继承的语法13.3 继承中成员变量的特点13.4 方法重写Override13.5 super关键字13.6 继承中构造方法的特点13.7 Object类13.8 继承的注意事项13.9 综合案例动物世界13.10 本章总结13.1 为什么需要继承假设我们要设计一个学校管理系统需要管理老师和学生// 老师类publicclassTeacher{privateStringname;privateintage;privateStringsubject;publicvoidintroduce(){System.out.println(我是老师叫name今年age岁);}}// 学生类publicclassStudent{privateStringname;privateintage;privateStringstudentId;publicvoidintroduce(){System.out.println(我是学生叫name今年age岁);}}问题name、age、introduce()在两个类中完全重复继承的出现就是为了解决这种代码重复问题。将公共代码提取到一个父类中子类自动获得父类的属性和方法。13.2 继承的语法13.2.1 基本语法// 父类基类/超类publicclass父类名{// 公共属性和方法}// 子类派生类publicclass子类名extends父类名{// 子类特有的属性和方法}13.2.2 示例人 → 老师/学生// 父类PersonpublicclassPerson{protectedStringname;// protected子类可访问protectedintage;publicPerson(){}publicPerson(Stringname,intage){this.namename;this.ageage;}publicvoidintroduce(){System.out.println(我叫name今年age岁);}publicvoideat(){System.out.println(name正在吃饭);}publicvoidsleep(){System.out.println(name正在睡觉);}}// 子类TeacherpublicclassTeacherextendsPerson{privateStringsubject;publicTeacher(){}publicTeacher(Stringname,intage,Stringsubject){super(name,age);// 调用父类构造方法this.subjectsubject;}publicvoidteach(){System.out.println(name正在教subject);}}// 子类StudentpublicclassStudentextendsPerson{privateStringstudentId;publicStudent(){}publicStudent(Stringname,intage,StringstudentId){super(name,age);this.studentIdstudentId;}publicvoidstudy(){System.out.println(name正在学习学号studentId);}}13.2.3 测试publicclassInheritTest{publicstaticvoidmain(String[]args){TeachertnewTeacher(王老师,35,Java);t.introduce();// 继承自Person我叫王老师今年35岁t.eat();// 继承自Person王老师正在吃饭t.teach();// 自己的方法王老师正在教JavaSystem.out.println(------);StudentsnewStudent(张三,20,2026001);s.introduce();// 继承自Person我叫张三今年20岁s.sleep();// 继承自Person张三正在睡觉s.study();// 自己的方法张三正在学习学号2026001}}13.3 继承中成员变量的特点13.3.1 变量访问规则当子类和父类有同名变量时遵循就近原则publicclassFu{intnum10;}publicclassZiextendsFu{intnum20;publicvoidshow(){intnum30;System.out.println(num);// 30局部变量System.out.println(this.num);// 20本类成员变量System.out.println(super.num);// 10父类成员变量}}13.3.2 三种变量对比关键字含义示例num就近原则优先局部System.out.println(num)this.num本类成员变量System.out.println(this.num)super.num父类成员变量System.out.println(super.num)13.4 方法重写Override13.4.1 什么是方法重写子类对父类中已有方法进行重新实现方法名、参数列表、返回类型必须相同。publicclassPerson{publicvoidintroduce(){System.out.println(我是一个人);}}publicclassTeacherextendsPerson{Override// 注解标识这是一个重写方法publicvoidintroduce(){System.out.println(我是一名老师);}}publicclassStudentextendsPerson{Overridepublicvoidintroduce(){System.out.println(我是一名学生);}}13.4.2 重写的规则规则说明方法名必须相同参数列表必须相同返回值类型必须相同或为其子类型访问权限不能比父类更严格可以更宽松Override建议加上编译器会检查是否正确重写13.4.3 重写 vs 重载对比重写Override重载Overload位置子类对父类同一个类中方法名相同相同参数列表相同不同返回值相同无要求访问权限不能更严格无要求目的覆盖父类行为提供多种调用方式13.4.4 重写的应用publicclassAnimal{publicvoidspeak(){System.out.println(动物发出声音);}publicStringtoString(){returnAnimal{};}}publicclassDogextendsAnimal{Overridepublicvoidspeak(){System.out.println(汪汪汪);}OverridepublicStringtoString(){returnDog{};}}publicclassCatextendsAnimal{Overridepublicvoidspeak(){System.out.println(喵喵喵~);}}13.5 super关键字super代表父类对象的引用。13.5.1 super的用法用法说明示例super.属性访问父类成员变量super.namesuper.方法()调用父类方法super.introduce()super(参数)调用父类构造方法super(张三, 20)13.5.2 示例publicclassTeacherextendsPerson{privateStringsubject;Overridepublicvoidintroduce(){super.introduce();// 先调用父类的方法System.out.println(我教的科目是subject);}}输出我叫王老师今年35岁 我教的科目是Java13.6 继承中构造方法的特点13.6.1 子类构造方法会调用父类构造方法publicclassFu{publicFu(){System.out.println(Fu的无参构造被调用);}}publicclassZiextendsFu{publicZi(){// 隐藏了一行super();System.out.println(Zi的无参构造被调用);}}ZiznewZi();输出Fu的无参构造被调用 Zi的无参构造被调用13.6.2 构造方法的执行顺序new Zi() 调用流程 1. → Zi() 的第一行隐含 super() 2. → Fu() 先执行 3. → Fu() 执行完毕后Zi() 继续执行规则子类构造方法中第一行必须调用父类构造方法。如果不写编译器自动加super()无参。13.6.3 使用super(参数)调用父类有参构造publicclassFu{publicFu(){System.out.println(Fu无参构造);}publicFu(Stringname){System.out.println(Fu有参构造name);}}publicclassZiextendsFu{publicZi(){super(张三);// 显式调用父类有参构造System.out.println(Zi无参构造);}}newZi();输出Fu有参构造张三 Zi无参构造⚠️ 注意this()和super()不能同时出现因为它们都必须在第一行。13.7 Object类13.7.1 Object是什么java.lang.Object是所有Java类的根基类。如果一个类没有显式继承任何类则默认继承Object。// 以下两种写法等价publicclassStudent{}publicclassStudentextendsObject{}13.7.2 Object的常用方法方法说明用途toString()返回对象的字符串表示打印对象信息equals(Object obj)比较对象是否相等对象比较hashCode()返回对象的哈希值集合中使用getClass()返回对象的运行时类反射clone()克隆对象对象复制finalize()GC回收前调用已废弃13.7.3 重写toString()publicclassStudent{privateStringname;privateintage;publicStudent(Stringname,intage){this.namename;this.ageage;}// 不重写toString输出地址值如 Student1b6d3586// 重写后OverridepublicStringtoString(){returnStudent{namename, ageage};}}StudentsnewStudent(张三,20);System.out.println(s);// 自动调用toString()// 输出Student{name张三, age20}13.7.4 重写equals()Overridepublicbooleanequals(Objectobj){if(thisobj)returntrue;if(objnull||getClass()!obj.getClass())returnfalse;Studentother(Student)obj;returnthis.ageother.agethis.name.equals(other.name);}比较方式说明基本类型比较值引用类型比较地址equals()默认比较地址可重写为比较内容13.8 继承的注意事项13.8.1 Java只支持单继承// ❌ 错误Java不支持多继承publicclassZiextendsFu1,Fu2{}但支持多层继承publicclassAnimal{}publicclassDogextendsAnimal{}publicclassHuskyextendsDog{}// Husky → Dog → Animal13.8.2 继承的使用场景适合继承不适合继承is-a 关系Dog is a Animalhas-a 关系Car has a Engine子类是父类的一种两者只是关联关系需要复用父类代码没有公共代码需要复用13.8.3 访问修饰符总结修饰符同类同包子类不同包子类不同包非子类public✅✅✅✅protected✅✅✅❌默认✅✅❌❌private✅❌❌❌13.9 综合案例动物世界// 父类publicclassAnimal{protectedStringname;protectedintage;publicAnimal(){}publicAnimal(Stringname,intage){this.namename;this.ageage;}publicvoideat(){System.out.println(name正在吃东西);}publicvoidsleep(){System.out.println(name正在睡觉);}OverridepublicStringtoString(){returnthis.getClass().getSimpleName(){namename, ageage};}}// 子类狗publicclassDogextendsAnimal{privateStringbreed;publicDog(Stringname,intage,Stringbreed){super(name,age);this.breedbreed;}publicvoidbark(){System.out.println(namebreed汪汪汪);}publicvoidfetch(){System.out.println(name去捡球了);}Overridepublicvoideat(){System.out.println(name正在吃狗粮);}}// 子类猫publicclassCatextendsAnimal{privatebooleanisIndoor;publicCat(Stringname,intage,booleanisIndoor){super(name,age);this.isIndoorisIndoor;}publicvoidmeow(){System.out.println(name喵喵喵~);}publicvoidscratch(){System.out.println(name在抓沙发);}Overridepublicvoideat(){System.out.println(name正在吃猫粮);}}// 子类鸟publicclassBirdextendsAnimal{privatebooleancanFly;publicBird(Stringname,intage,booleancanFly){super(name,age);this.canFlycanFly;}publicvoidsing(){System.out.println(name在唱歌叽叽喳喳);}publicvoidfly(){if(canFly){System.out.println(name展翅高飞);}else{System.out.println(name不会飞...);}}}测试类publicclassAnimalTest{publicstaticvoidmain(String[]args){DogdognewDog(旺财,3,金毛);CatcatnewCat(咪咪,2,true);BirdbirdnewBird(小黄,1,true);Animal[]animals{dog,cat,bird};System.out.println( 动物园 );for(Animala:animals){System.out.println(a);// 调用toStringa.eat();// 调用重写后的eata.sleep();// 继承父类的sleepSystem.out.println(---);}// 子类特有方法dog.bark();dog.fetch();cat.meow();bird.fly();}}13.10 本章总结知识回顾知识点核心内容继承子类 extends 父类获得父类属性和方法方法重写子类重新实现父类的方法加Overridesuper访问父类成员变量、方法、构造方法构造方法子类构造默认先调用super()先父后子Object类所有类的根基常用toString和equals单继承Java只支持单继承但支持多层继承练习题设计一个Shape父类包含getArea()方法。创建Circle和Rectangle子类分别实现计算面积。重写equals()和toString()方法使其比较和显示对象内容。 互动时间Java为什么不支持多继承这样设计有什么好处方法重写和方法重载的区别是什么下篇预告[14-多态]—— 学习面向对象最核心的特性多态 参考资料Oracle Java 官方文档 - Inheritance《Java核心技术 卷I》第5章《Effective Java》第3版