授课语音

Java 继承

继承是面向对象编程中的一项重要特性,它允许一个类继承另一个类的属性和方法,从而实现代码的复用和功能的扩展。在 Java 中,继承通过 extends 关键字来实现。继承使得我们可以创建一个新的类,继承已有类的属性和方法,并在此基础上进行扩展和修改,避免了重复的代码编写。

1. 认识继承

继承的核心思想是“子类继承父类的属性和行为”。通过继承,子类不仅可以拥有父类的成员变量和方法,还可以在子类中添加新的功能,或修改父类的部分实现。继承有助于提高代码的可复用性和可维护性。Java 是单继承的,即每个类只能直接继承一个父类。

语法:

class 子类名 extends 父类名 {
    // 子类特有的成员变量和方法
}

2. 权限修饰符

在继承中,父类的成员变量和方法的访问权限受到权限修饰符的限制。Java 提供了四种访问控制修饰符:

  • public:对所有类可见。
  • protected:对子类及同包中的其他类可见。
  • default(无修饰符):仅对子类及同包中的类可见。
  • private:仅对本类可见。

在继承中,子类可以访问父类的 publicprotected 成员,但是不能直接访问父类的 private 成员。如果需要访问父类的私有成员,可以通过父类提供的公有方法进行间接访问。

3. 继承后的特点

继承后的主要特点包括:

  1. 子类继承父类的成员变量和方法:子类会继承父类所有的 publicprotected 成员变量及方法,且子类可以访问父类的这些成员。
  2. 子类可以访问父类的构造器:但是,父类的构造器不能直接被子类继承。子类在构造时会隐式地调用父类的构造器(默认调用父类的无参构造器),如果父类有带参构造器,子类可以通过 super 关键字显式调用父类的构造器。
  3. 子类可以重写父类的方法:子类可以重写(覆盖)父类的方法,实现不同的功能,但方法的名称和参数列表必须与父类的方法相同。

4. 方法重写

方法重写是指子类重新实现父类中已经存在的方法,目的是对父类方法进行修改或扩展。方法重写是多态的基础之一,允许子类提供不同的实现。

重写规则:

  • 子类重写父类方法时,方法名、返回类型和参数列表必须与父类方法一致。
  • 子类重写方法时,可以改变方法的访问权限,但不能缩小访问权限。
  • 子类可以通过 super 关键字调用父类的被重写方法。

代码示例:

class Animal {
    // 父类的成员变量
    String name;

    // 父类的构造器
    public Animal(String name) {
        this.name = name;
    }

    // 父类的方法
    public void sound() {
        System.out.println("动物发出声音");
    }
}

class Dog extends Animal {
    // 子类构造器
    public Dog(String name) {
        super(name);  // 调用父类构造器
    }

    // 重写父类的sound方法
    @Override
    public void sound() {
        System.out.println(name + " 发出汪汪声");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("小狗");
        dog.sound();  // 调用子类重写的方法
    }
}

解释:

  • Dog 类继承了 Animal 类,并重写了 sound 方法。
  • sound 方法中,子类提供了一个特定的实现,输出 Dog 类特有的声音。

5. 方法重写的应用场景

方法重写通常用于以下几种情况:

  1. 多态:通过方法重写,子类可以提供不同的实现方式,增强了程序的灵活性和可扩展性。
  2. 扩展功能:子类可以在继承父类的基础上重写某些方法,来适应新的需求。
  3. 实现接口:当子类实现接口时,它需要重写接口中的所有抽象方法。

6. 子类构造器的特点和场景

子类构造器负责初始化子类的对象。在创建子类对象时,构造器会首先隐式调用父类的无参构造器,如果父类没有无参构造器,子类就需要显式调用父类的带参构造器。子类可以在构造器中执行一些特定的初始化操作。

子类构造器的特点:

  1. 子类构造器默认会调用父类的构造器,如果父类没有无参构造器,则必须显式调用父类的带参构造器。
  2. 子类构造器必须在创建对象时执行,并且它会初始化子类特有的成员变量。

代码示例:

class Parent {
    public Parent(String name) {
        System.out.println("父类构造器: " + name);
    }
}

class Child extends Parent {
    public Child(String name) {
        super(name);  // 显式调用父类的构造器
        System.out.println("子类构造器: " + name);
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child("张三");
    }
}

解释:

  • 子类 Child 在构造器中通过 super 显式调用了父类 Parent 的构造器。首先输出父类的构造器内容,然后输出子类构造器的内容。

7. 子类构造器调用其他构造器

子类构造器不仅可以调用父类的构造器,还可以通过 this 关键字调用同一个类中的其他构造器。这种情况通常用于构造器重载,当子类有多个构造器时,可以通过 this 来共享代码,避免重复编写初始化操作。

代码示例:

class Person {
    String name;
    int age;

    // 无参构造器
    public Person() {
        this("默认名字", 18);  // 调用另一个构造器
    }

    // 带参构造器
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void show() {
        System.out.println("姓名: " + name + ", 年龄: " + age);
    }
}

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person();  // 使用无参构造器
        Person person2 = new Person("李四", 25);  // 使用带参构造器
        person1.show();
        person2.show();
    }
}

解释:

  • Person 类通过无参构造器调用了带参构造器,避免了代码的重复编写。构造器内部通过 this 关键字来实现不同构造器之间的调用。

总结

继承是面向对象编程的核心概念之一,它通过类的层次结构实现了代码复用和功能扩展。在 Java 中,继承帮助我们构建层次分明的类结构,使得程序更加模块化、易于维护。掌握继承的基本知识,包括权限修饰符、方法重写、子类构造器等内容,可以使我们更加熟练地使用 Java 进行面向对象的开发。

去1:1私密咨询

系列课程: