1. 引言

在Java中,接口是一种核心概念,常用于定义契约、实现多态或创建新的抽象层次。为代码编写更具可读性的接口名称是开发过程中的重要步骤。

本教程将探讨Java接口的命名规范。

2. Java接口的命名约定

首先,让我们回顾一下Java接口的基本用途。在探索Java内置库的源代码时,我们通常会遇到两种主要用例。

接口主要用于提供其他类的能力或实现多态。在这些情况下,Java有相应的命名规则。

特别地,函数式接口没有特定的命名模式,因此这里暂不讨论。

2.1. 接口作为能力

能力定义了一个对象如果实现了接口可以做什么。在这种情况下,接口名称通常是形容词。例如,Comparable 接口就是一个遵循形容词命名规则的例子:

public interface Comparable<T>

Comparable 的一个实现是 Integer 类,其签名如下:

public final class Integer implements Comparable<Integer>

这意味着 Integer 定义了一个可以与其他 Integer 对象进行比较的对象。

其他以形容词命名的接口还有 RunnableCallable,它们定义了对象作为多线程编程中任务使用的功能。

2.2. 接口作为多态类型

Java库中广泛使用的一种模式是多态性,通过将接口作为具有两个或多个实现的超类型来实现。当使用接口实现多态时,接口名称通常是名词。此外,子类的名称结合了它们的专业性和接口名称。以 List 接口为例:

public interface List<E> extends Collection<E>

List 的一个多态实现——LinkedList 的签名如下:

public class LinkedList<E> implements List<E>

另一个 List 实现是 ArrayList

public class ArrayList<E> implements List<E>

这两个类的名称中都包含 "List",并且它们的专业名称是 "Array" 和 "Linked",基于内部实现。因此,我们有 ArrayListLinkedList

Connection 接口,用于定义数据库连接类型,也是Java库中遵循此类命名规则的一个例子。

3. 实践Java命名规范

为了演示这一规则的应用,我们将使用一个多态的 User 类型,它具备标识能力。首先,定义 Identifiable 接口:

public interface Identifiable {
    void identify();
}

接下来,创建继承自 IdentifiableUser 接口:

public interface User extends Identifiable {
    void authorize();
}

User 分为 RootUserRegularUser 两种实现。

首先,创建 RegularUser 类:

public class RegularUser implements User {
    @Override
    public void identify() {
        // some implementation
    }

    @Override
    public void authorize() {
        // some implementation
    }
}

然后,定义 User 的另一种实现——RootUser 类:

public class RootUser implements User {
    @Override
    public void identify() {
        // some implementation
    }

    @Override
    public void authorize() {
        // some implementation
    }
}

如你所见,我们遵循了Java的命名规则。能力接口 Identifiable 以形容词命名,而多态类型 User 及其子类 RootUserRegularUser 以名词命名。

这种命名方式使得代码更易于阅读。从接口名称就能看出用户是可以被识别的,它可以是根用户或普通用户。代码更接近自然语言,提高了可读性

4. 不正确的接口命名示例

在企业级Java应用中,另一种常见的模式来自匈牙利命名法。本节简要讨论前缀 "I" 和 "Impl" 后缀模式,并解释为什么应避免使用它们。

前缀 "I" 模式建议所有接口名称以大写字母 "I" 开头,这是为了表示接口的缩写。这在C#中更为常见,因为没有关键词来区分接口实现与继承。然而,在Java中,我们可以通过查看 "implements" 和 "extends" 关键字来区分实现和继承,所以这个区别并不必要。

"Impl" 后缀模式意味着将接口的实现而不是接口本身命名。因此,所有实现名称将以 "Impl" 结尾。这通常出现在只有一个实现的接口时,我们找不到一个真正反映其特化的名称。但是,由于类签名显示了它是实现某个东西,所以 "Impl" 一词并没有增加任何信息

因此,**我们必须避免使用 "I" 或 "Impl" 前缀或后缀来命名接口和类,如 UserImplIUserIIdentifiableIdentifiableImpl**。

5. 总结

本教程探讨了不同类型的接口命名规范。

Java规范将接口名称转化为更接近自然语言的形式,有助于提高代码的可读性和维护性。

命名规范取决于个人喜好和公司标准。然而,Java应用程序通常更符合Java内置库的命名习惯**。

如往常一样,源代码可在GitHub上找到。