学习java37天

Java 继承 (Inheritance)

继承是面向对象三大特性(封装、继承、多态)之一。它是一种代码复用类关系建模的机制。

一、继承的基本概念

  • 定义 :Java使用 extends 关键字建立类与类之间的继承关系。

  • 语法

    java

    复制代码
    public class 子类 extends 父类 {
        // 子类特有的属性和方法
    }
  • 术语

    • 子类 (Subclass):也叫派生类。继承的类。

    • 父类 (Superclass):也叫超类、基类。被继承的类。

  • 目的

    1. 代码复用:将多个子类共有的属性和行为抽取到父类中,避免代码重复。

    2. 功能扩展:子类在继承父类功能的基础上,可以添加自己特有的功能。

    3. 建立"is-a"关系 :继承代表一种"子类是父类的一种"的逻辑关系(例如:Student is a Person)。

二、何时使用继承?

必须同时满足以下两个条件:

  1. 存在共性内容:多个类之间存在大量相同的属性或方法。

  2. 逻辑关系成立 :在逻辑上满足 "子类是父类的一种" 的关系。不能仅仅为了复用代码而滥用继承。

三、继承的特点

  1. 单继承 :Java只支持单继承,一个类只能有一个直接父类。

  2. 不支持多继承 :一个类不能同时 extends 多个父类。(但可以通过接口实现类似功能)。

  3. 支持多层继承:继承可以传递(A继承B,B继承C)。

    java

    复制代码
    class A extends B {} // A的直接父类是B
    class B extends C {} // B的直接父类是C
    // 最终,A间接继承了C。
  4. 所有类的根 :在Java中,每个类都直接或间接继承自 java.lang.Object 类(Object 类是所有类的超类)。

四、继承中成员的访问特点

1. 成员变量访问

遵循 "就近原则"

  • 查找顺序局部变量 → 子类成员变量 (this) → 父类成员变量 (super)

  • 关键字

    • this.变量名:明确指定访问本类的成员变量。

    • super.变量名:明确指定访问父类的成员变量。

示例

java

复制代码
class Person {
    String name = "PersonName";
}
class Student extends Person {
    String name = "StudentName";
    
    public void show(String name) {
        System.out.println(name);        // 局部变量,就近原则
        System.out.println(this.name);   // 子类的成员变量 "StudentName"
        System.out.println(super.name);  // 父类的成员变量 "PersonName"
    }
}
2. 成员方法访问

访问规则与成员变量相同(就近原则)。关键在于方法的重写 (Override)

五、方法的重写 (Override)

1. 定义与时机
  • 定义 :在继承体系中,子类 出现了一个与父类方法声明(方法名、参数列表)完全相同的方法。

  • 时机 :当从父类继承来的方法不能满足子类特定的需求时,就需要重写。

2. 格式与注解
  • 格式:子类方法的声明(方法名、参数列表)必须与父类方法一致。

  • @Override 注解

    • 这是一个安全校验注解,加在子类重写的方法上。

    • 作用:由编译器检查该方法是否真的成功重写了父类方法。如果由于拼写错误等原因导致没有正确重写,编译器会报错。

    • 强烈建议重写时都加上此注解,保证代码安全、意图清晰。

3. 重写的核心规则 (重要!)
  1. 方法名与形参列表 :必须与父类被重写的方法完全相同

  2. 访问权限 :子类方法的访问权限必须 >= 父类方法的访问权限。

    • public > protected > 默认(package-private) > private

    • 例如:父类是 protected,子类可以是 protectedpublic,但不能是默认或 private

  3. 返回值类型

    • 基本数据类型/void:必须完全相同

    • 引用数据类型:子类方法的返回值类型可以是父类方法返回值类型的子类(即"小于等于")。

  4. 重写范围 :只有被声明为 private、非final、非static 的实例方法(通常指进入了"虚方法表"的方法)才能被重写。

示例

java

复制代码
class Animal {
    public void eat() {
        System.out.println("动物吃东西");
    }
    protected Animal getInstance() {
        return new Animal();
    }
}
class Cat extends Animal {
    @Override // 正确:重写了eat方法
    public void eat() {
        System.out.println("猫吃鱼");
    }
    @Override // 正确:返回值类型是Animal的子类
    public Cat getInstance() {
        return new Cat();
    }
}

六、继承中构造方法的访问特点

  1. 构造方法不能被继承:子类不能继承父类的构造方法。

  2. 隐式调用子类任何构造方法的第一行,都默认隐含了 super(),即先调用父类的无参构造。

    java

    复制代码
    public Student() {
        super(); // 默认存在,且必须在第一行
        // ... 子类构造后续代码
    }
  3. 显式调用 :如果父类没有无参构造,或者你想调用父类的有参构造,必须在子类构造方法的第一行使用 super(参数) 明确指定

  4. this(...)super(...) 在构造方法中不能共存,因为它们都要求位于第一行。

七、thissuper 关键字总结

关键字 含义 调用位置
this 代表当前对象的引用(在内存中的地址)。 1. 访问本类成员变量:this.变量名 2. 访问本类成员方法:this.方法名() 3. 访问本类其他构造器:this(...) (必须第一行)
super 代表父类存储空间的标识(可以理解为父类对象的引用,但不等同于父类对象)。 1. 访问父类成员变量:super.变量名 2. 访问父类成员方法:super.方法名() 3. 访问父类构造器:super(...) (必须第一行)

核心区别this 指向当前实例本身,super 是子类中访问父类成员的桥梁,它不是一个独立的对象。

java 复制代码
package extensdemotext;

public class Employee {
    private  String id;
    private  String name;
    private  String position;

    public Employee() {
    }

    public Employee(String id, String name,String position) {
        this.id = id;
        this.name = name;
        this.position = position;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getPosition(){
        return position;
    }
    public void setPosition(String position){
        this.position = position;
    }

    public void work(){
        System.out.println("员工在工作");
    }
}


package extensdemotext;

public class Teacher extends Employee{
    public Teacher() {
    }

    public Teacher(String id, String name,String position) {
        super(id, name, position);
    }

    @Override
    public void work(){
        System.out.println("教研部员工正在工作");
    }
}


package extensdemotext;

public class AdminStaff extends  Employee {
    public AdminStaff() {
    }

    public AdminStaff(String id, String name, String position) {
        super(id, name, position);
    }
    @Override
    public void work(){
        System.out.println("行政部员工在工作");
    }
}


package extensdemotext;

public class Lecturer extends Teacher{
    public Lecturer() {
    }

    public Lecturer(String id, String name,String position) {
        super(id, name, position);
    }
    @Override
    public void work(){
        System.out.println(getName()+"在上课");
    }
}


package extensdemotext;

public class Tutor extends Teacher{
    public Tutor() {
    }

    public Tutor(String id, String name,String position) {
        super(id, name,position);
    }
    @Override
    public void work(){
        System.out.println(getName()+"在批改作业");
    }
}

package extensdemotext;

public class Maintainer extends AdminStaff{
    public Maintainer() {
    }

    public Maintainer(String id, String name,String position) {
        super(id, name,position);
    }
    @Override
    public void work(){
        System.out.println(getName()+"在维护设施");
    }
}


package extensdemotext;

public class Buyer extends AdminStaff{

    public Buyer() {
    }

    public Buyer(String id, String name,String position) {
        super(id, name,position);
    }

    @Override
    public void work(){
        System.out.println(getName()+"在采购");
    }
}


package extensdemotext;

public class Test {
    public static void main(String[] args) {
        Lecturer l = new Lecturer("001","zhangsan","讲师");
        //System.out.println(l.getId()+", "+l.getName()+", "+l.getPosition());
        Tutor t = new Tutor("002","lisi","助教");
        Maintainer m = new Maintainer("003","wangwu","维护专员");
        Buyer b = new Buyer("004","zhaoniu","采购专员");
        l.work();
        t.work();
        m.work();
        b.work();




    }
}
相关推荐
xifangge20253 小时前
PHP 接口跨域调试完整解决方案附源码(从 0 到定位问题)
开发语言·php
go_bai3 小时前
Linux-网络基础
linux·开发语言·网络·笔记·学习方法·笔记总结
WJSKad12353 小时前
果园树干识别与定位_faster-rcnn_x101-32x4d_fpn_1x_coco改进实践
python
深蓝电商API3 小时前
Scrapy中间件实战:自定义请求头和代理池实现
python·scrapy·中间件
hui函数4 小时前
Python系列Bug修复|如何解决 pip install 安装报错 invalid command ‘bdist_wheel’(缺少 wheel)问题
python·bug·pip
好大哥呀4 小时前
C++ IDE
开发语言·c++·ide
hui函数4 小时前
Python系列Bug修复|如何解决 pip install -r requirements.txt 私有索引未设为 trusted-host 导致拒绝 问题
python·bug·pip
子午4 小时前
【2026原创】动物识别系统~Python+深度学习+人工智能+模型训练+图像识别
人工智能·python·深度学习
o_insist4 小时前
LangChain1.0 实现 PDF 文档向量检索全流程
人工智能·python·langchain