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
对象进行比较的对象。
其他以形容词命名的接口还有 Runnable
和 Callable
,它们定义了对象作为多线程编程中任务使用的功能。
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",基于内部实现。因此,我们有 ArrayList
和 LinkedList
。
Connection
接口,用于定义数据库连接类型,也是Java库中遵循此类命名规则的一个例子。
3. 实践Java命名规范
为了演示这一规则的应用,我们将使用一个多态的 User
类型,它具备标识能力。首先,定义 Identifiable
接口:
public interface Identifiable {
void identify();
}
接下来,创建继承自 Identifiable
的 User
接口:
public interface User extends Identifiable {
void authorize();
}
User
分为 RootUser
和 RegularUser
两种实现。
首先,创建 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
及其子类 RootUser
和 RegularUser
以名词命名。
这种命名方式使得代码更易于阅读。从接口名称就能看出用户是可以被识别的,它可以是根用户或普通用户。代码更接近自然语言,提高了可读性。
4. 不正确的接口命名示例
在企业级Java应用中,另一种常见的模式来自匈牙利命名法。本节简要讨论前缀 "I" 和 "Impl" 后缀模式,并解释为什么应避免使用它们。
前缀 "I" 模式建议所有接口名称以大写字母 "I" 开头,这是为了表示接口的缩写。这在C#中更为常见,因为没有关键词来区分接口实现与继承。然而,在Java中,我们可以通过查看 "implements" 和 "extends" 关键字来区分实现和继承,所以这个区别并不必要。
"Impl" 后缀模式意味着将接口的实现而不是接口本身命名。因此,所有实现名称将以 "Impl" 结尾。这通常出现在只有一个实现的接口时,我们找不到一个真正反映其特化的名称。但是,由于类签名显示了它是实现某个东西,所以 "Impl" 一词并没有增加任何信息。
因此,**我们必须避免使用 "I" 或 "Impl" 前缀或后缀来命名接口和类,如 UserImpl
、IUser
、IIdentifiable
和 IdentifiableImpl
**。
5. 总结
本教程探讨了不同类型的接口命名规范。
Java规范将接口名称转化为更接近自然语言的形式,有助于提高代码的可读性和维护性。
命名规范取决于个人喜好和公司标准。然而,Java应用程序通常更符合Java内置库的命名习惯**。
如往常一样,源代码可在GitHub上找到。