Java中的继承

1. 继承的核心概念与实现

定义
Java 通过 extends 关键字实现类之间的继承关系,子类继承父类的非私有成员(成员变量和方法)。

public class Dog extends Animal { 
    // 子类特有属性和方法
}

核心特点

  • 单继承模式一个类只能有一个直接父类(避免多继承的复杂性)。
  • 多层继承支持链式继承(如 Object → Animal → Dog)。
  • 默认继承:所有类隐式继承 Object 类(若未显式继承其他类)。 Object 类是“祖宗类”!!!!

内存原理

  • 子类对象包含父类成员变量,存储于堆内存中。
  • 方法调用时,JVM 通过方法区中的类信息确定执行逻辑。

2. 权限修饰符与访问控制

四大修饰符的访问范围

修饰符本类同包类子类任意位置
private✔️
缺省✔️✔️
protected✔️✔️✔️
public✔️✔️✔️✔️

使用场景

  • private:隐藏敏感数据(如密码字段)。
  • protected:允许子类访问,但限制其他包的非子类访问。
  • public:开放工具类方法或常量。

示例

public class BankAccount {
    private String password;  // 仅本类可访问
    protected double balance; // 子类可访问
    public static final String BANK_CODE = "CITI"; // 全局可访问
}

3. 方法重写(Override)

定义
子类重写父类方法以定制自身行为,方法签名(名称、参数列表)必须与父类一致。

重写规范

声明不变,重新实现!!!!!!

规则与注意事项

  1. 访问权限:子类方法权限 ≥ 父类(如父类为 protected,子类可为 protected/public)。
  2. 返回值类型:必须相同或更具体(协变返回类型)。
  3. 异常声明:子类方法抛出的异常 ≤ 父类方法。
  4. 不可重写的方法privatestaticfinal 方法。

注解 @Override

  • 显式声明方法重写,编译器会检查格式是否正确。
  • 提高代码可读性,避免拼写错误导致意外重载。

示例

// 父类
public class Shape {
    public double calculateArea() {
        return 0.0;
    }
}

// 子类重写
public class Circle extends Shape {
    private double radius;
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

经典应用:重写 toString()

  • 注意1:直接输出对象,默认会调用Object的toString方法(可以省略不写调用toString的代码),默认返回对象的地址信息
  • 注意2:输出对象的地址实际上是没有什么意义的,开发中更希望输出对象时看对象的内容信息,所以子类需要重写Object的toString方法。以便以后输出对象时默认就近调用子类重写的toString方法返回对象的内容
public class Student {
    private String name;
    private int age;

    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + "}";
    }
}

4. 构造器调用规则

子类构造器的执行逻辑

  1. 隐式调用:若未显式调用父类构造器,默认调用 super()(父类无参构造器)。
  2. 显式调用:若父类没有无参构造器,必须手动调用 super(参数)
  3. 构造器链:通过 this() 调用同类其他构造器,但必须位于第一行。

代码示例

// 父类
public class Person {
    private String name;
    public Person(String name) { // 有参构造器
        this.name = name;
    }
}

// 子类必须显式调用 super
public class Student extends Person {
    private String school;
    
    public Student(String name, String school) {
        super(name); // 必须显式调用父类构造器
        this.school = school;
    }
    
    public Student(String name) {
        this(name, "黑马程序员"); // 调用同类其他构造器
    }
}

注意事项

  • super()this() 必须位于构造器首行,二者不能共存。
  • 若父类构造器包含初始化逻辑(如数据库连接),子类需确保正确调用。

5. 成员访问的"就近原则"

访问顺序

  1. 子类局部变量 → 子类成员变量 → 父类成员变量
  2. 若父类成员被隐藏,使用 super 关键字强制访问。

示例

public class Parent {
    String name = "Parent";
}

public class Child extends Parent {
    String name = "Child";
    
    public void printNames() {
        String name = "Local";
        System.out.println(name);        // 输出 Local
        System.out.println(this.name);   // 输出 Child
        System.out.println(super.name);  // 输出 Parent
    }
}

6. 总结与最佳实践

  • 优先组合:通过持有对象(has-a)代替继承(is-a),提高灵活性。
  • 合理封装:使用 privateprotected 控制成员访问,避免数据暴露。
  • 明确继承关系:仅在逻辑上严格符合层次结构时使用继承(如 Dog is an Animal)。
  • 利用注解@Override 提升代码可读性,@Deprecated 标记过时方法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值