跳到主要内容

Java 继承

提示
  1. Java 继承基本概念:继承是 Java 面向对象编程的核心特性,允许从一个现有类(超类)创建新类(子类),继承超类的方法和属性。
  2. 继承的实现与示例:使用 extends 关键字实现继承,子类可以访问超类的方法和属性。子类可覆盖超类方法(方法覆盖),并使用 super 关键字调用超类方法。
  3. 继承类型与使用场景:Java 支持单继承、多层继承和分层继承,不支持多重继承(可通过接口实现)。继承用于代码重用和实现运行时多态。

继承是面向对象编程(OOP)的关键特性之一,它允许我们从现有类创建一个新类。

创建的新类被称为子类(child 或 derived class),而作为子类来源的现有类被称为超类(superclass 或 base class)。

在 Java 中,使用 extends 关键字来实现继承。例如,

class Animal {
// 方法和字段
}

// 使用 extends 关键字
// 来实现继承
class Dog extends Animal {

// Animal 的方法和字段
// Dog 的方法和字段
}

在上面的示例中,Dog 类通过继承 Animal 类的方法和字段来创建。

这里,Dog 是子类,Animal 是超类。

示例 1:Java 继承

class Animal {

// 父类的字段和方法
String name;
public void eat() {
System.out.println("我可以吃");
}
}

// 继承自 Animal
class Dog extends Animal {

// 子类中的新方法
public void display() {
System.out.println("我的名字是 " + name);
}
}

class Main {
public static void main(String[] args) {

// 创建子类的对象
Dog labrador = new Dog();

// 访问超类的字段
labrador.name = "Rohu";
labrador.display();

// 使用子类的对象
// 调用超类的方法
labrador.eat();

}
}

输出

我的名字是 Rohu
我可以吃

在上述示例中,我们从超类 Animal 派生了一个子类 Dog。注意以下语句,

labrador.name = "Rohu";

labrador.eat();

这里,labradorDog 的一个对象。然而,nameeat()Animal 类的成员。

由于 Dog 继承了 Animal 的字段和方法,我们可以使用 Dog 的对象来访问这些字段和方法。

子类 Dog 可以访问超类 Animal 的字段和方法。

is-a 关系

在 Java 中,继承是一种is-a关系。也就是说,只有在两个类之间存在 is-a 关系时,我们才使用继承。例如,

  • Car 是一种 Vehicle
  • Orange 是一种 Fruit
  • Surgeon 是一种 Doctor
  • Dog 是一种 Animal

这里,Car 可以从 Vehicle 继承,Orange 可以从 Fruit 继承,等等。

Java 继承中的方法覆盖

示例 1中,我们看到子类的对象可以访问超类的方法。

但是,如果超类和子类中都存在相同的方法,会发生什么?

在这种情况下,子类中的方法会覆盖超类中的方法。这个概念被称为 Java 中的方法覆盖。

示例 2:Java 继承中的方法覆盖

class Animal {

// 超类中的方法
public void eat() {
System.out.println("我可以吃");
}
}

// Dog 继承 Animal
class Dog extends Animal {

// 覆盖 eat() 方法
@Override
public void eat() {
System.out.println("我吃狗粮");
}

// 子类中的新方法
public void bark() {
System.out.println("我可以汪汪叫");
}
}

class Main {
public static void main(String[] args) {

// 创建子类的对象
Dog labrador = new Dog();

// 调用 eat() 方法
labrador.eat();
labrador.bark();
}
}

输出

我吃狗粮
我会叫

在上面的例子中,eat() 方法同时存在于超类 Animal 和子类 Dog 中。

这里,我们创建了一个 Dog 类的对象 labrador

现在当我们使用对象 labrador 调用 eat() 方法时,会调用 Dog 中的方法。这是因为派生类中的方法覆盖了基类中的方法。

这就叫做方法重写。想了解更多,请访问 Java 方法重写

注意:我们使用了 @Override 注解来告诉编译器我们正在重写一个方法。然而,这个注解并不是强制性的。想了解更多,请访问 Java 注解

Java 继承中的 super 关键字

前面我们看到,在子类中相同的方法会覆盖超类中的方法。

在这种情况下,super 关键字用于从子类的方法中调用父类的方法。

示例 3:继承中的 super 关键字

class Animal {

// 超类中的方法
public void eat() {
System.out.println("我会吃");
}
}

// Dog 继承 Animal
class Dog extends Animal {

// 重写 eat() 方法
@Override
public void eat() {

// 调用超类的方法
super.eat();
System.out.println("我吃狗粮");
}

// 子类中的新方法
public void bark() {
System.out.println("我会叫");
}
}

class Main {
public static void main(String[] args) {

// 创建子类的对象
Dog labrador = new Dog();

// 调用 eat() 方法
labrador.eat();
labrador.bark();
}
}

输出

我会吃
我吃狗粮
我会叫

在上面的例子中,eat() 方法同时存在于基类 Animal 和派生类 Dog 中。注意这条语句,

super.eat();

这里,super 关键字用于调用超类中的 eat() 方法。

我们也可以使用 super 关键字从子类的构造器中调用超类的构造器。想了解更多,请访问 Java super 关键字

继承中的 protected 成员

在 Java 中,如果一个类包含 protected 字段和方法,那么这些字段和方法可以被这个类的子类访问。

示例 4:继承中的 protected 成员

class Animal {
protected String name;

protected void display() {
System.out.println("我是一只动物。");
}
}

class Dog extends Animal {

public void getInfo() {
System.out.println("我的名字是 " + name);
}
}

class Main {
public static void main(String[] args) {

// 创建子类的对象
Dog labrador = new Dog();

// 使用子类对象访问 protected 字段和方法
labrador.name = "Rocky";
labrador.display();

labrador.getInfo();
}
}

输出

我是一只动物。
我的名字是 Rocky

在上面的例子中,我们创建了一个名为 Animal 的类。该类包含一个 protected 字段:name 和一个方法:display()

我们继承了 Dog 类从 Animal。注意这条语句,

labrador.name = "Rocky";
labrador.display();

这里,我们可以使用子类 labrador 的对象来访问超类中的 protected 字段和方法。

为什么使用继承?

  • 继承在 Java 中最重要的用途是代码重用。父类中的代码可以被子类直接使用。
  • 方法重写也被称为运行

时多态。因此,我们可以通过继承在 Java 中实现多态。

继承的类型

继承有五种类型。

1. 单继承

在单继承中,一个子类只继承自一个超类。例如,

类 A 继承自类 B。

2. 多层继承

在多层继承中,一个子类继承自一个超类,然后这个子类又作为超类为另一个类所继承。例如,

类 B 继承自类 A,类 C 继承自类 B。

3. 分层继承

在分层继承中,多个子类继承自一个超类。例如,

类 B 和类 C 都继承自类 A。

4. 多重继承

在多重继承中,一个子类继承自多个超类。例如,

类 C 继承自类 A 和类 B。

注意:Java 不支持多重继承。然而,我们可以通过接口实现多重继承。想了解更多,请访问 Java 实现多重继承

5. 混合继承

混合继承是两种或多种继承类型的结合。例如,

类 B 和 C 继承自类 A,类 D 继承自类 B 和 C。

这里,我们结合了分层继承和多重继承形成了混合继承。