Java 继承
- Java 继承基本概念:继承是 Java 面向对象编程的核心特性,允许从一个现有类(超类)创建新类(子类),继承超类的方法和属性。
- 继承的实现与示例:使用
extends
关键字实现继承,子类可以访问超类的方法和属性。子类可覆盖超类方法(方法覆盖),并使用super
关键字调用超类方法。 - 继承类型与使用场景: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();
这里,labrador
是 Dog
的一个对象。然而,name
和 eat()
是 Animal
类的成员。
由于 Dog
继承了 Animal
的字段和方法,我们可以使用 Dog
的对象来访问这些字段和方法。
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. 单继承
在单继承中,一个子类只继承自一个超类。例如,
2. 多层继承
在多层继承中,一个子类继承自一个超类,然后这个子类又作为超类为另一个类所继承。例如,
3. 分层继承
在分层继承中,多个子类继承自一个超类。例如,
4. 多重继承
在多重继承中,一个子类继承自多个超类。例如,
注意:Java 不支持多重继承。然而,我们可以通过接口实现多重继承。想了解更多,请访问 Java 实现多重继承。