Documentation

The Java™ Tutorials
Hide TOC
Overriding and Hiding Methods重写方法和隐藏方法
Trail: Learning the Java Language
Lesson: Interfaces and Inheritance
Section: Inheritance

Overriding and Hiding Methods重写方法和隐藏方法

Instance Methods实例方法

An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.子类中的实例方法与超类中的实例方法具有相同的签名(名称,加上其参数的编号和类型)和返回类型,将覆盖超类的方法。

The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. 子类重写方法的能力允许类从行为“足够接近”的超类继承,然后根据需要修改行为。The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. 重写方法具有与其重写的方法相同的名称、参数数量和类型以及返回类型。An overriding method can also return a subtype of the type returned by the overridden method. 重写方法还可以返回重写方法返回的类型的子类型。This subtype is called a covariant return type.此子类型称为协变返回类型

When overriding a method, you might want to use the @Override annotation that instructs the compiler that you intend to override a method in the superclass. 重写方法时,您可能希望使用@Override注释来指示编译器您打算重写超类中的方法。If, for some reason, the compiler detects that the method does not exist in one of the superclasses, then it will generate an error. 如果出于某种原因,编译器检测到某个超类中不存在该方法,那么它将生成一个错误。For more information on @Override, see Annotations.有关@Override的详细信息,请参阅注释

Static Methods静态方法

If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.如果子类定义的静态方法与超类中的静态方法具有相同的签名,则子类中的方法将隐藏超类中的方法。

The distinction between hiding a static method and overriding an instance method has important implications:隐藏静态方法和重写实例方法之间的区别具有重要意义:

Consider an example that contains two classes. 考虑一个包含两个类的示例。The first is Animal, which contains one instance method and one static method:第一个是Animal,它包含一个实例方法和一个静态方法:

public class Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Animal");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Animal");
    }
}

The second class, a subclass of Animal, is called Cat:第二类是Animal的一个子类,叫做Cat

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod();
        myAnimal.testInstanceMethod();
    }
}

The Cat class overrides the instance method in Animal and hides the static method in Animal. Cat类重写Animal中的实例方法,并隐藏Animal中的静态方法。The main method in this class creates an instance of Cat and invokes testClassMethod() on the class and testInstanceMethod() on the instance.此类中的main方法创建Cat实例,并在类上调用testClassMethod(),在实例上调用testInstanceMethod()

The output from this program is as follows:该程序的输出如下所示:

The static method in Animal
The instance method in Cat

As promised, the version of the hidden static method that gets invoked is the one in the superclass, and the version of the overridden instance method that gets invoked is the one in the subclass.正如所承诺的,被调用的隐藏静态方法的版本是超类中的版本,而被调用的被重写实例方法的版本是子类中的版本。

Interface Methods接口方法

Default methods and abstract methods in interfaces are inherited like instance methods. 接口中的默认方法抽象方法与实例方法一样被继承。However, when the supertypes of a class or interface provide multiple default methods with the same signature, the Java compiler follows inheritance rules to resolve the name conflict. 但是,当类或接口的超类型提供具有相同签名的多个默认方法时,Java编译器将遵循继承规则来解决名称冲突。These rules are driven by the following two principles:这些规则由以下两个原则驱动:

If two or more independently defined default methods conflict, or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. 如果两个或多个独立定义的默认方法冲突,或者默认方法与抽象方法冲突,那么Java编译器将生成编译器错误。You must explicitly override the supertype methods.必须显式重写超类型方法。

Consider the example about computer-controlled cars that can now fly. 考虑一下计算机控制的汽车现在可以飞行的例子。You have two interfaces (OperateCar and FlyCar) that provide default implementations for the same method, (startEngine):您有两个接口(OperateCarFlyCar),为同一方法(startEngine)提供默认实现:

public interface OperateCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}
public interface FlyCar {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Implementation
    }
}

A class that implements both OperateCar and FlyCar must override the method startEngine. 同时实现OperateCarFlyCar的类必须重写startEngine方法。You could invoke any of the of the default implementations with the super keyword.您可以使用super关键字调用任何默认实现。

public class FlyingCar implements OperateCar, FlyCar {
    // ...
    public int startEngine(EncryptedKey key) {
        FlyCar.super.startEngine(key);
        OperateCar.super.startEngine(key);
    }
}

The name preceding super (in this example, FlyCar or OperateCar) must refer to a direct superinterface that defines or inherits a default for the invoked method. super前面的名称(在本例中为FlyCarOperateCar)必须引用定义或继承调用方法默认值的直接super接口。This form of method invocation is not restricted to differentiating between multiple implemented interfaces that contain default methods with the same signature. 这种方法调用形式并不局限于区分包含具有相同签名的默认方法的多个实现接口。You can use the super keyword to invoke a default method in both classes and interfaces.您可以使用super关键字在类和接口中调用默认方法。

Inherited instance methods from classes can override abstract interface methods. 从类继承的实例方法可以重写抽象接口方法。Consider the following interfaces and classes:考虑下面的接口和类:

public interface Mammal {
    String identifyMyself();
}
public class Horse {
    public String identifyMyself() {
        return "I am a horse.";
    }
}
public class Mustang extends Horse implements Mammal {
    public static void main(String... args) {
        Mustang myApp = new Mustang();
        System.out.println(myApp.identifyMyself());
    }
}

The method Mustang.identifyMyself returns the string I am a horse. 方法Mustang.identifyMyself返回字符串I am a horse.The class Mustang inherits the method identifyMyself from the class Horse, which overrides the abstract method of the same name in the interface Mammal.Mustang类从Horse类继承identifyMyself方法,该方法重写接口Mammal中同名的抽象方法。

Note: Static methods in interfaces are never inherited.注意:接口中的静态方法永远不会被继承。

Modifiers修饰符

The access specifier for an overriding method can allow more, but not less, access than the overridden method. 重写方法的访问说明符可以允许比重写方法更多但不更少的访问。For example, a protected instance method in the superclass can be made public, but not private, in the subclass.例如,超类中受保护的实例方法可以在子类中公开,而不是私有。

You will get a compile-time error if you attempt to change an instance method in the superclass to a static method in the subclass, and vice versa.如果试图将超类中的实例方法更改为子类中的静态方法,则会出现编译时错误,反之亦然。

Summary小结

The following table summarizes what happens when you define a method with the same signature as a method in a superclass.下表总结了使用与超类中的方法相同的签名定义方法时发生的情况。

Defining a Method with the Same Signature as a Superclass's Method定义与超类的方法具有相同签名的方法
  Superclass Instance Method超类实例方法 Superclass Static Method超类静态法
Subclass Instance Method子类实例方法 Overrides覆盖 Generates a compile-time error生成编译时错误
Subclass Static Method子类静态法 Generates a compile-time error生成编译时错误 Hides兽皮

Note: In a subclass, you can overload the methods inherited from the superclass. 在子类中,可以重载从超类继承的方法。Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass. 这种重载方法既不隐藏也不重写超类实例方法—它们是子类特有的新方法。

Previous page: Multiple Inheritance of State, Implementation, and Type
Next page: Polymorphism