13 继承
2026/6/4 15:13:25 网站建设 项目流程

目录

  • 🧬 13 继承
    • 📑 目录
    • 13.1 为什么需要继承
    • 13.2 继承的语法
      • 13.2.1 基本语法
      • 13.2.2 示例:人 → 老师/学生
      • 13.2.3 测试
    • 13.3 继承中成员变量的特点
      • 13.3.1 变量访问规则
      • 13.3.2 三种变量对比
    • 13.4 方法重写(Override)
      • 13.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 方法重写(Override)
  • 13.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+"岁");}}

问题nameageintroduce()在两个类中完全重复

继承的出现就是为了解决这种代码重复问题。将公共代码提取到一个父类中,子类自动获得父类的属性和方法。


13.2 继承的语法

13.2.1 基本语法

// 父类(基类/超类)publicclass父类名{// 公共属性和方法}// 子类(派生类)publicclass子类名extends父类名{// 子类特有的属性和方法}

13.2.2 示例:人 → 老师/学生

// 父类:PersonpublicclassPerson{protectedStringname;// protected:子类可访问protectedintage;publicPerson(){}publicPerson(Stringname,intage){this.name=name;this.age=age;}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.subject=subject;}publicvoidteach(){System.out.println(name+"正在教"+subject);}}
// 子类:StudentpublicclassStudentextendsPerson{privateStringstudentId;publicStudent(){}publicStudent(Stringname,intage,StringstudentId){super(name,age);this.studentId=studentId;}publicvoidstudy(){System.out.println(name+"正在学习,学号:"+studentId);}}

13.2.3 测试

publicclassInheritTest{publicstaticvoidmain(String[]args){Teachert=newTeacher("王老师",35,"Java");t.introduce();// 继承自Person:我叫王老师,今年35岁t.eat();// 继承自Person:王老师正在吃饭t.teach();// 自己的方法:王老师正在教JavaSystem.out.println("------");Students=newStudent("张三",20,"2026001");s.introduce();// 继承自Person:我叫张三,今年20岁s.sleep();// 继承自Person:张三正在睡觉s.study();// 自己的方法:张三正在学习,学号:2026001}}

13.3 继承中成员变量的特点

13.3.1 变量访问规则

当子类和父类有同名变量时,遵循就近原则

publicclassFu{intnum=10;}publicclassZiextendsFu{intnum=20;publicvoidshow(){intnum=30;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 方法重写(Override)

13.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(){return"Animal{}";}}publicclassDogextendsAnimal{@Overridepublicvoidspeak(){System.out.println("汪汪汪!");}@OverridepublicStringtoString(){return"Dog{}";}}publicclassCatextendsAnimal{@Overridepublicvoidspeak(){System.out.println("喵喵喵~");}}

13.5 super关键字

super代表父类对象的引用

13.5.1 super的用法

用法说明示例
super.属性访问父类成员变量super.name
super.方法()调用父类方法super.introduce()
super(参数)调用父类构造方法super("张三", 20)

13.5.2 示例

publicclassTeacherextendsPerson{privateStringsubject;@Overridepublicvoidintroduce(){super.introduce();// 先调用父类的方法System.out.println("我教的科目是:"+subject);}}

输出

我叫王老师,今年35岁 我教的科目是:Java

13.6 继承中构造方法的特点

13.6.1 子类构造方法会调用父类构造方法

publicclassFu{publicFu(){System.out.println("Fu的无参构造被调用");}}publicclassZiextendsFu{publicZi(){// 隐藏了一行:super();System.out.println("Zi的无参构造被调用");}}
Ziz=newZi();

输出

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.name=name;this.age=age;}// 不重写toString:输出地址值如 Student@1b6d3586// 重写后:@OverridepublicStringtoString(){return"Student{name='"+name+"', age="+age+"}";}}
Students=newStudent("张三",20);System.out.println(s);// 自动调用toString()// 输出:Student{name='张三', age=20}

13.7.4 重写equals()

@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(obj==null||getClass()!=obj.getClass())returnfalse;Studentother=(Student)obj;returnthis.age==other.age&&this.name.equals(other.name);}
比较方式说明
==基本类型比较值,引用类型比较地址
equals()默认比较地址,可重写为比较内容

13.8 继承的注意事项

13.8.1 Java只支持单继承

// ❌ 错误!Java不支持多继承publicclassZiextendsFu1,Fu2{}

但支持多层继承

publicclassAnimal{}publicclassDogextendsAnimal{}publicclassHuskyextendsDog{}// Husky → Dog → Animal

13.8.2 继承的使用场景

适合继承不适合继承
is-a 关系(Dog is a Animal)has-a 关系(Car has a Engine)
子类是父类的一种两者只是关联关系
需要复用父类代码没有公共代码需要复用

13.8.3 访问修饰符总结

修饰符同类同包子类不同包子类不同包非子类
public
protected
默认
private

13.9 综合案例:动物世界

// 父类publicclassAnimal{protectedStringname;protectedintage;publicAnimal(){}publicAnimal(Stringname,intage){this.name=name;this.age=age;}publicvoideat(){System.out.println(name+"正在吃东西");}publicvoidsleep(){System.out.println(name+"正在睡觉");}@OverridepublicStringtoString(){returnthis.getClass().getSimpleName()+"{name='"+name+"', age="+age+"}";}}
// 子类:狗publicclassDogextendsAnimal{privateStringbreed;publicDog(Stringname,intage,Stringbreed){super(name,age);this.breed=breed;}publicvoidbark(){System.out.println(name+"("+breed+")汪汪汪!");}publicvoidfetch(){System.out.println(name+"去捡球了!");}@Overridepublicvoideat(){System.out.println(name+"正在吃狗粮");}}
// 子类:猫publicclassCatextendsAnimal{privatebooleanisIndoor;publicCat(Stringname,intage,booleanisIndoor){super(name,age);this.isIndoor=isIndoor;}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.canFly=canFly;}publicvoidsing(){System.out.println(name+"在唱歌:叽叽喳喳!");}publicvoidfly(){if(canFly){System.out.println(name+"展翅高飞!");}else{System.out.println(name+"不会飞...");}}}

测试类

publicclassAnimalTest{publicstaticvoidmain(String[]args){Dogdog=newDog("旺财",3,"金毛");Catcat=newCat("咪咪",2,true);Birdbird=newBird("小黄",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 父类,获得父类属性和方法
方法重写子类重新实现父类的方法,加@Override
super访问父类成员变量、方法、构造方法
构造方法子类构造默认先调用super(),先父后子
Object类所有类的根基,常用toString和equals
单继承Java只支持单继承,但支持多层继承

练习题

  1. 设计一个Shape父类,包含getArea()方法。创建CircleRectangle子类分别实现计算面积。
  2. 重写equals()toString()方法,使其比较和显示对象内容。

💬 互动时间

  • Java为什么不支持多继承?这样设计有什么好处?
  • 方法重写和方法重载的区别是什么?

📢下篇预告:[14-多态]—— 学习面向对象最核心的特性:多态!


📚 参考资料

  • Oracle Java 官方文档 - Inheritance
  • 《Java核心技术 卷I》第5章
  • 《Effective Java》第3版

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询