Documentation

The Java™ Tutorials
Hide TOC
Inheritance继承
Trail: Learning the Java Language
Lesson: Interfaces and Inheritance

Inheritance遗产

In the preceding lessons, you have seen inheritance mentioned several times. 在前面的课程中,您已经多次提到了继承In the Java language, classes can be derived from other classes, thereby inheriting fields and methods from those classes.在Java语言中,类可以从其他类派生,从而从这些类继承字段和方法。


Definitions:定义: A class that is derived from another class is called a subclass (also a derived class, extended class, or child class). 从另一个类派生的类称为子类(也称为派生类扩展类子类)。The class from which the subclass is derived is called a superclass (also a base class or a parent class).派生子类的类称为超类(也是基类父类)。

Excepting Object, which has no superclass, every class has one and only one direct superclass (single inheritance). 除了没有超类的Object之外,每个类都有一个且只有一个直接超类(单继承)。In the absence of any other explicit superclass, every class is implicitly a subclass of Object.在没有任何其他显式超类的情况下,每个类都隐式地是Object的子类。

Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and ultimately derived from the topmost class, Object. 类可以从从从类派生的类派生的类派生,依此类推,并最终从最顶层的类Object派生。Such a class is said to be descended from all the classes in the inheritance chain stretching back to Object. 这样一个类被称为继承链中所有类的后代,这些类可以追溯到Object

The idea of inheritance is simple but powerful: When you want to create a new class and there is already a class that includes some of the code that you want, you can derive your new class from the existing class. 继承的思想很简单,但功能强大:当您想要创建一个新类,并且已经有一个类包含您想要的一些代码时,您可以从现有类派生新类。In doing this, you can reuse the fields and methods of the existing class without having to write (and debug!) them yourself.通过这样做,您可以重用现有类的字段和方法,而无需编写(和调试!)你自己动手吧。

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. 子类从其超类继承所有成员(字段、方法和嵌套类)。Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.构造函数不是成员,因此它们不会被子类继承,但是可以从子类调用超类的构造函数。

The Java Platform Class HierarchyJava平台类层次结构

The Object class, defined in the java.lang package, defines and implements behavior common to all classes—including the ones that you write. java.lang包中定义的Object类定义并实现了所有类共有的行为—包括你写的那些。In the Java platform, many classes derive directly from Object, other classes derive from some of those classes, and so on, forming a hierarchy of classes.在Java平台中,许多类直接从Object派生,其他类从其中的一些类派生,依此类推,形成了类的层次结构。

All Classes in the Java Platform are Descendants of Object

All Classes in the Java Platform are Descendants of ObjectJava平台中的所有类都是对象的后代

At the top of the hierarchy, Object is the most general of all classes. 在层次结构的顶部,Object是所有类中最通用的。Classes near the bottom of the hierarchy provide more specialized behavior.靠近层次结构底部的类提供了更专门的行为。

An Example of Inheritance继承的例子

Here is the sample code for a possible implementation of a Bicycle class that was presented in the Classes and Objects lesson:以下是在“类和对象”课程中介绍的Bicycle类的可能实现的示例代码:

public class Bicycle {
        
    // the Bicycle class has three fields
    public int cadence;
    public int gear;
    public int speed;
        
    // the Bicycle class has one constructor
    public Bicycle(int startCadence, int startSpeed, int startGear) {
        gear = startGear;
        cadence = startCadence;
        speed = startSpeed;
    }
        
    // the Bicycle class has four methods
    public void setCadence(int newValue) {
        cadence = newValue;
    }
        
    public void setGear(int newValue) {
        gear = newValue;
    }
        
    public void applyBrake(int decrement) {
        speed -= decrement;
    }
        
    public void speedUp(int increment) {
        speed += increment;
    }
        
}

A class declaration for a MountainBike class that is a subclass of Bicycle might look like this:作为Bicycle类的子类的MountainBike类的类声明可能如下所示:

public class MountainBike extends Bicycle {
        
    // the MountainBike subclass adds one field
    public int seatHeight;

    // the MountainBike subclass has one constructor
    public MountainBike(int startHeight,
                        int startCadence,
                        int startSpeed,
                        int startGear) {
        super(startCadence, startSpeed, startGear);
        seatHeight = startHeight;
    }   
        
    // the MountainBike subclass adds one method
    public void setHeight(int newValue) {
        seatHeight = newValue;
    }   
}

MountainBike inherits all the fields and methods of Bicycle and adds the field seatHeight and a method to set it. MountainBike继承了Bicycle的所有字段和方法,并添加了字段seatHeight和设置它的方法。Except for the constructor, it is as if you had written a new MountainBike class entirely from scratch, with four fields and five methods. 除了构造函数之外,就好像您完全从头开始编写了一个新的MountainBike类,包含四个字段和五个方法。However, you didn't have to do all the work. 然而,你不必做所有的工作。This would be especially valuable if the methods in the Bicycle class were complex and had taken substantial time to debug.如果Bicycle类中的方法很复杂,并且需要花费大量时间进行调试,那么这将特别有价值。

What You Can Do in a Subclass在子类中可以做什么

A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. 子类继承其父类的所有公开成员和受保护成员,而不管该子类在哪个包中。If the subclass is in the same package as its parent, it also inherits the package-private members of the parent. 如果子类与其父类位于同一个包中,则它还继承父类的包私有成员。You can use the inherited members as is, replace them, hide them, or supplement them with new members:您可以按原样使用继承的成员、替换它们、隐藏它们或用新成员补充它们:

The following sections in this lesson will expand on these topics.本课程中的以下部分将对这些主题进行扩展。

Private Members in a Superclass超类中的私有成员

A subclass does not inherit the private members of its parent class. 子类不继承其父类的private成员。However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。

A nested class has access to all the private members of its enclosing class—both fields and methods. 嵌套类可以访问其封闭类的所有私有成员—字段和方法。Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.因此,子类继承的公共或受保护的嵌套类可以间接访问超类的所有私有成员。

Casting Objects强制转换对象的类型

We have seen that an object is of the data type of the class from which it was instantiated. 我们已经看到,对象的数据类型与从中实例化它的类的数据类型相同。For example, if we write例如,如果我们编写

public MountainBike myBike = new MountainBike();

then myBike is of type MountainBike.那么myBike就属于MountainBike类型。

MountainBike is descended from Bicycle and Object. MountainBikeBicycleObject的后代。Therefore, a MountainBike is a Bicycle and is also an Object, and it can be used wherever Bicycle or Object objects are called for.因此,MountainBike既是Bicycle也是Object,它可以在任何需要BicycleObject的地方使用。

The reverse is not necessarily true: a Bicycle may be a MountainBike, but it isn't necessarily. 反过来不一定正确:Bicycle可能MountainBike,但不一定是。Similarly, an Object may be a Bicycle or a MountainBike, but it isn't necessarily.类似地,Object可能BicycleMountainBike,但不一定是。

Casting shows the use of an object of one type in place of another type, among the objects permitted by inheritance and implementations. 强制转换显示在继承和实现所允许的对象中,使用一种类型的对象代替另一种类型的对象。For example, if we write例如,如果我们编写

Object obj = new MountainBike();

then obj is both an Object and a MountainBike (until such time as obj is assigned another object that is not a MountainBike). obj既是一个Object又是一个MountainBike(直到obj被指定为另一个非MountainBike的对象)。This is called implicit casting.这称为隐式强制转换

If, on the other hand, we write另一方面,如果我们编写

MountainBike myBike = obj;

we would get a compile-time error because obj is not known to the compiler to be a MountainBike. 我们会得到一个编译时错误,因为编译器不知道objMountainBikeHowever, we can tell the compiler that we promise to assign a MountainBike to obj by explicit casting:但是,我们可以告诉编译器,我们承诺通过显式强制转换MountainBike分配给obj

MountainBike myBike = (MountainBike)obj;

This cast inserts a runtime check that obj is assigned a MountainBike so that the compiler can safely assume that obj is a MountainBike. 此强制转换插入一个运行时检查,确保obj被分配了一个MountainBike,以便编译器可以安全地假定obj是一个MountainBikeIf obj is not a MountainBike at runtime, an exception will be thrown.如果obj在运行时不是MountainBike,则会抛出异常。


Note: You can make a logical test as to the type of a particular object using the instanceof operator. 可以使用instanceof操作符对特定对象的类型进行逻辑测试。This can save you from a runtime error owing to an improper cast. 这可以避免由于不正确的强制转换而导致的运行时错误。For example:例如:
if (obj instanceof MountainBike) {
    MountainBike myBike = (MountainBike)obj;
}

Here the instanceof operator verifies that obj refers to a MountainBike so that we can make the cast with knowledge that there will be no runtime exception thrown.在这里,instanceof操作符验证obj引用了一个MountainBike,这样我们就可以在知道不会抛出运行时异常的情况下进行转换。



Previous page: Questions and Exercises: Interfaces
Next page: Multiple Inheritance of State, Implementation, and Type