JLS 如何指定术语 "abstract method"、"concrete method" 和 "default method"?

How does the JLS specify the terms "abstract method", "concrete method" and "default method"?

我看过"divergent"术语抽象方法具体方法默认方法的定义 在一些 Whosebug 答案中。

Java 语言规范给出的真正定义是什么?请在您的回答中包含相关的支持 JLS 参考资料。

下面的链接/节号取自 Java 11 版本的 Java 语言规范。

根据JLS 8.4.3.1

"An abstract method declaration introduces the method as a member, providing its signature (§8.4.2), result (§8.4.5), and throws clause if any (§8.4.6), but does not provide an implementation (§8.4.7). A method that is not abstract may be referred to as a concrete method."

根据JLS 9.4

"A default method is an instance method declared in an interface with the default modifier. Its body is always represented by a block, which provides a default implementation for any class that implements the interface without overriding the method. Default methods are distinct from concrete methods (§8.4.3.1), which are declared in classes, and from private interface methods, which are neither inherited nor overridden."

所以根据这个分类法,实际上有 4 种方法:

  • 抽象方法,
  • 具体方法,
  • 默认方法和
  • 私有接口方法

请注意,JLS 8.4.3.1 在区分抽象方法和具体方法时没有提及 finalstatic

这些修饰符不能与 abstract 关键字一起使用。这意味着 staticfinal 的方法必须是具体方法。 强化具体方法的 8.4.3.1 定义。

抽象方法

抽象方法在 Java 语言规范 (JLS) Section 8.4.3.1 中定义为:

An abstract method declaration introduces the method as a member, providing its signature (§8.4.2), result (§8.4.5), and throws clause if any (§8.4.6), but does not provide an implementation (§8.4.7).

实际上,抽象方法是定义了签名但未提供实现的任何方法。例如,接口中的方法和抽象class中用abstract关键字限定的方法都是抽象方法:

public interface Foo {
    void someAbstractMethod();
}

public abstract class Bar {

    public abstract someAbstractMethod();

    // ...

}

具体方法

根据JLSSection 8.4.3.1,具体方法定义为:

A method that is not abstract may be referred to as a concrete method.

实际上,这意味着提供实现的任何方法:

public FooImpl implements Foo {

    @Override
    public void someAbstractMethod() {
        // ... some implementation ...
    }

}

默认方法

JLS 中定义了默认方法Section 9.4:

A default method is an instance method declared in an interface with the default modifier. Its body is always represented by a block, which provides a default implementation for any class that implements the interface without overriding the method. Default methods are distinct from concrete methods (§8.4.3.1), which are declared in classes, and from private interface methods, which are neither inherited nor overridden.

同节还补充:

An interface can declare static methods, which are invoked without reference to a particular object. static interface methods are distinct from default methods, which are instance methods.

默认方法是为特定目的而创建的。在JDK 8中,功能接口被添加到Java。这需要更新接口以包含功能方法,但这样做需要 所有 这些接口的现有实现(包括在第 3 方库和框架中)将需要提供实现。相反,Java 团队引入了默认方法,这些方法是提供默认实现的接口方法,当未通过覆盖 classes 提供实现时使用该默认实现。

不应将其用作抽象 classes 的替代方法。它旨在用于特定目的,应该用于该目的。

实际上,默认方法是使用 default 关键字创建的:

public interface Foo {

    public default void someMethod() {
        // ... some default implementation ...
    }
}

这个默认实现可以在具体子classes:

中被覆盖
public class FooImpl implements Foo {

    @Override
    public void someMethod() {
        // ... some overriding implementation ...
    }
}

此外,根据 JLS Section 9.4.1.1,可以使用 super 关键字在具体子classes 中访问方法的默认实现(默认方法的主体) , 由接口名称限定:

An overridden default method can be accessed by using a method invocation expression (§15.12) that contains the keyword super qualified by a superinterface name.

例如:

public class FooImpl implements Foo {

    @Override
    public void someMethod() {
        Foo.super.someMethod();
    }
}

接口名称用作限定符,因为class可以实现多个接口(或者一个接口可以扩展多个接口)。有关详细信息,请参阅 Explicitly calling a default method in Java