Java继承知识笔记

📅 2026/6/19 11:57:07
Java继承知识笔记
Java 继承复习笔记重点覆盖 Java 继承、super、构造顺序、访问权限、继承方式、final、继承与组合。1. 为什么需要继承在 Java 中类用来描述现实世界中的对象。很多类之间会存在共同特征例如狗和猫都有name、age、eat()、sleep()等共同成员。如果每个类都重复写这些字段和方法会导致代码重复多后期维护困难共性逻辑无法统一管理。继承的核心作用抽取共性实现代码复用。例如classAnimal{Stringname;intage;publicvoideat(){System.out.println(name正在吃饭);}publicvoidsleep(){System.out.println(name正在睡觉);}}classDogextendsAnimal{publicvoidbark(){System.out.println(name汪汪汪~~~);}}classCatextendsAnimal{publicvoidmew(){System.out.println(name喵喵喵~~~);}}Dog和Cat继承Animal后可以直接复用name、age、eat()、sleep()只需要新增自己特有的行为。2. 继承的基本概念继承 inheritance是面向对象中实现代码复用的重要机制。它允许程序员在保留已有类特征的基础上扩展新功能。常见术语术语含义父类 / 基类 / 超类被继承的类例如Animal子类 / 派生类继承父类的类例如Dog、Cat继承关系子类获得父类的成员并在此基础上扩展新成员继承体现的是一种is-a关系。例如狗是动物Dog is an Animal猫是动物Cat is an Animal3. 继承的语法Java 中使用extends表示继承关系。修饰符class子类extends父类{// 子类新增成员}示例publicclassDogextendsAnimal{publicvoidbark(){System.out.println(name汪汪汪~~~);}}注意子类会继承父类中的成员变量和成员方法。子类继承父类后应该添加自己特有的成员否则继承的意义不大。Java 中类的继承是单继承一个类只能直接继承一个父类。4. 子类访问父类成员4.1 访问成员变量在子类方法中访问成员变量时遵循就近原则子类自己有该成员变量优先访问子类自己的子类没有则向父类中查找父类也没有则编译报错如果子类和父类有同名成员变量直接访问时访问的是子类自己的成员变量。示例classBase{inta;intb;intc;}classDerivedextendsBase{inta;charb;publicvoidmethod(){a100;// 访问子类自己的 ab101;// 访问子类自己的 bc102;// 子类没有 c访问父类继承下来的 c}}重点同名字段不会形成重写而是字段隐藏。直接写字段名时优先找当前类。想访问父类同名字段需要使用super。4.2 访问成员方法如果子类和父类方法名不同优先在子类中找子类没有再去父类中找都没有则编译报错。示例classBase{publicvoidmethodA(){System.out.println(Base中的methodA());}}classDerivedextendsBase{publicvoidmethodB(){System.out.println(Derived中的methodB());}publicvoidmethodC(){methodB();// 访问子类自己的方法methodA();// 访问父类继承下来的方法}}如果父类和子类有同名方法参数列表不同构成重载根据调用时传递的参数决定调用哪个方法参数列表相同构成重写直接调用时优先执行子类重写后的方法想在子类中调用父类被重写的方法需要使用super.方法名()。5.super关键字当子类和父类中存在同名成员时直接访问通常会访问子类自己的成员。此时可以使用super明确访问父类成员。5.1 访问父类成员变量classBase{inta;intb;}classDerivedextendsBase{inta;charb;publicvoidmethod(){this.a100;// 子类自己的 athis.b101;// 子类自己的 bsuper.a200;// 父类中的 asuper.b201;// 父类中的 b}}5.2 访问父类成员方法classBase{publicvoidmethodB(){System.out.println(Base中的methodB());}}classDerivedextendsBase{OverridepublicvoidmethodB(){System.out.println(Derived中的methodB());}publicvoidmethodC(){methodB();// 调用子类重写后的 methodBsuper.methodB();// 调用父类中的 methodB}}5.3super使用注意事项super主要用于在子类中访问父类成员。super只能在非静态方法或构造方法中使用。super.成员变量用来访问父类字段。super.成员方法()用来访问父类方法。super(...)用来调用父类构造方法且必须放在子类构造方法第一行。6. 子类构造方法创建子类对象时必须先构造父类部分再构造子类部分。口诀先有父再有子。示例classBase{publicBase(){System.out.println(Base());}}classDerivedextendsBase{publicDerived(){// 默认隐藏了 super();System.out.println(Derived());}}publicclassTest{publicstaticvoidmain(String[]args){DeriveddnewDerived();}}输出结果Base() Derived()构造方法规则子类构造方法中默认会隐式调用父类无参构造方法super()。如果父类没有无参构造方法子类必须显式调用父类的带参构造方法。super(...)必须是子类构造方法中的第一条语句。一个构造方法中super(...)只能出现一次。super(...)和this(...)不能同时出现在同一个构造方法中因为它们都要求放在第一行。示例父类只有带参构造时子类必须显式调用。classPerson{Stringname;intage;publicPerson(Stringname,intage){this.namename;this.ageage;}}classStudentextendsPerson{publicStudent(Stringname,intage){super(name,age);// 必须调用父类构造方法}}7.this和super的区别对比项thissuper含义当前对象的引用子类对象中从父类继承下来的那部分成员的访问入口访问字段访问本类成员变量访问父类成员变量访问方法调用本类方法调用父类方法构造方法中this(...)调用本类其他构造方法super(...)调用父类构造方法是否默认存在用户不写this(...)就没有构造方法中默认会有super()前提是父类存在无参构造使用位置非静态方法、构造方法非静态方法、构造方法相同点都是 Java 关键字都不能在静态方法中直接使用在构造方法中调用时都必须放在第一行this(...)和super(...)不能同时出现在同一个构造方法中。8. 初始化顺序8.1 没有继承关系时执行顺序静态代码块 - 实例代码块 - 构造方法特点静态代码块在类加载阶段执行只执行一次。每创建一次对象实例代码块和构造方法都会执行一次。实例代码块先于构造方法执行。8.2 有继承关系时创建子类对象时执行顺序父类静态代码块 子类静态代码块 父类实例代码块 父类构造方法 子类实例代码块 子类构造方法第二次创建子类对象时静态代码块不会再执行只执行实例代码块和构造方法父类实例代码块 父类构造方法 子类实例代码块 子类构造方法记忆口诀静态先行父类优先实例随后构造最后。9.protected和访问权限Java 中常见访问限定符访问范围private默认权限 defaultprotectedpublic同一个类中可以可以可以可以同一个包中的其他类不可以可以可以可以不同包中的子类不可以不可以可以可以不同包中的非子类不可以不可以不可以可以重点理解private成员在子类中不能直接访问。父类的private成员虽然不能被子类直接访问但仍然属于父类对象的一部分也会存在于子类对象中。protected常用于希望子类可以访问、但不想完全公开给所有类的成员。default只能在同包中访问跨包不可见。public访问范围最大。编码建议能用更严格权限就不要随便用public字段一般建议设为private只把必要的方法暴露为public专门给子类使用的成员可以考虑protected。10. Java 支持的继承方式Java 类继承支持10.1 单继承一个子类直接继承一个父类。classA{}classBextendsA{}10.2 多层继承一个类继承另一个类另一个类再继承更上层的类。classA{}classBextendsA{}classCextendsB{}10.3 不同类继承同一个父类多个子类继承同一个父类。classAnimal{}classDogextendsAnimal{}classCatextendsAnimal{}10.4 Java 不支持类的多继承一个类不能同时继承多个父类。错误示例classA{}classB{}// Java 中不允许这样写classCextendsA,B{}注意Java 类不支持多继承继承层次不宜过深一般不建议超过三层继承关系层次太深应考虑重构。11.final关键字与继承final可以修饰变量、方法和类。11.1 修饰变量表示常量初始化后不能再修改。finalinta10;// a 20; // 编译错误11.2 修饰类表示该类不能被继承。publicfinalclassAnimal{}// 编译错误final 类不能被继承classBirdextendsAnimal{}Java 中常用的String类就是final修饰的不能被继承。11.3 修饰方法表示该方法不能被子类重写。classAnimal{publicfinalvoideat(){System.out.println(吃饭);}}classDogextendsAnimal{// 编译错误final 方法不能被重写// public void eat() {}}12. 继承与组合继承和组合都能实现代码复用但表达的关系不同。方式表达关系示例继承is-a是一种狗是动物猫是动物组合has-a有一个 / 由……组成汽车有轮胎、发动机、车载系统12.1 组合示例classTire{// 轮胎类}classEngine{// 发动机类}classVehicleSystem{// 车载系统类}classCar{privateTiretire;privateEngineengine;privateVehicleSystemvehicleSystem;}汽车不是轮胎也不是发动机而是“有轮胎”“有发动机”因此更适合用组合。12.2 继承示例classCar{}classBenzextendsCar{}奔驰是一种汽车因此可以用继承。12.3 选择原则优先判断关系符合is-a可以考虑继承符合has-a应该使用组合如果只是为了复用代码不一定要继承一般建议能用组合尽量用组合。13. 易错点总结Java 中继承关键字是extends不是extend。Java 类只支持单继承不支持一个类同时继承多个父类。子类对象创建时一定先调用父类构造方法。子类构造方法中如果没有写super(...)编译器会默认添加super()。如果父类没有无参构造方法子类必须显式调用父类带参构造。super(...)必须是构造方法第一行。this(...)和super(...)不能同时出现在同一个构造方法中。子类和父类字段同名时字段不会重写只是隐藏。父类private成员不能在子类中直接访问。protected在不同包的子类中可以访问但不同包的非子类不能访问。final修饰的类不能被继承。final修饰的方法不能被重写。继承层次不要设计得太复杂过深时应考虑组合或重构。14. 快速记忆版继承语法class 子类 extends 父类 继承关系is-a 组合关系has-a 成员访问先找子类找不到再找父类 父类同名成员super.成员名 父类构造调用super(...) 构造顺序先父类后子类 初始化顺序父静 - 子静 - 父实例 - 父构造 - 子实例 - 子构造 访问权限private default protected public final 类不能被继承 final 方法不能被重写 final 变量不能被修改 设计原则能用组合尽量用组合