Java编程语言已经发展了超过二十年。在如此长的时间内,没有其他编程语言能够发展如此之大,同时还能保持对其传统代码库的支持。Java始终提供最大程度的向后兼容性,同时与大多数当前编程语言中可用的新功能保持同步。
Java编程语言主要是关于开发四种类型的-类,接口,枚举和注释。枚举和注释从Java 5开始出现。在本文中,我想谈谈Java编程语言中接口类型的演变。
Java中的接口最初设计为抽象类型,可用于类型的多种继承。在Java 1.0中,接口定义只能包含两种成员:静态常量和抽象方法:
public interface SomeInterface {
int SOME_CONSTANT = 35; // variable declaration
int abstractMethod(int x, int y); // method declaration
}
接口中的所有变量声明将始终是公共静态和最终声明,并且需要进行赋值。除此之外,接口中的所有方法都是公共的和抽象的。
接口中只有抽象方法,没有方法的实现,这使它可以用于类型的多重继承,同时仍然避免了多重继承的菱形问题。
类可以继承接口的抽象方法或提供实现。当相同的方法签名出现在超类以及正在实现的接口中时,则该方法是从超类而不是从接口继承的。
Java 1.1引入了内部类的概念,其中类可以是类的成员。从Java 2开始,我们有了静态的嵌套类和接口,它们也可以在接口内部使用。因此,从Java 2开始,我们在接口中有四种成员:静态常量,抽象方法,嵌套类和嵌套接口:
public interface SomeInterface {
int SOME_CONSTANT = 35; // variable declaration
int abstractMethod(int x, int y); // method declaration
// nested class definition
class NestedClass {
// members of a class
}
// nested interface definition
interface NestedInterface {
// member of an interface
}
}
接口中定义的所有嵌套类和接口将始终是公共的和静态的。
后来,发布了Java 5,其中包含许多新功能。它介绍了泛型以及新的枚举和注释类型。
Java 5中引入的泛型与类型参数有关。我们有通用类,通用接口和通用方法。类,接口和方法,可以使用类型参数进行定义。因此,从Java 5起,我们可以在接口中使用静态常量,抽象方法,嵌套类,嵌套接口,嵌套枚举和嵌套注释来拥有六种类型的成员。
// generic interface with one type parameter T
public interface SomeInterface<T> {
int SOME_CONSTANT = 35; // variable declaration
int abstractMethod(int x, int y); // method declaration
T abstractMethodUsingGenericType(T[] array, int i); // method using type parameter
// nested class definition
class NestedClass {
// members of a class
}
// nested interface definition
interface NestedInterface {
// member of an interface
}
// nested enum definition
enum NestedEnum {
OBJECT1,
OBJECT2,
;
// methods, variables and constructors
}
// nested annotation definition
@interface NestedAnnotation {
String attrib1();
}
}
接口定义中的类型参数T仅可用于抽象方法的返回类型和抽象方法的参数。不能与静态成员一起使用。嵌套的枚举和注释始终是公共的和静态的。
Java的一个重要特征一直是其向后兼容性。尽管该语言已经发展了多年,但仍非常谨慎地支持遗留代码库。所有较新的Java版本始终能够编译和运行较旧的源代码,而无需对代码进行任何更改。这种支持通常是有代价的。接口就是一个例子。接口的关键特性是它只能具有抽象方法。为了实现向后兼容性,不能轻易更改此行为,从而几乎不可能用较新的方法来增强API中的现有接口。考虑自Java 2以来就存在的List <E>接口。希望为List <E>引入一种排序方法,
为了解决此问题,Java 8在接口中添加了默认方法作为成员。这允许使用新方法来增强接口,从而为新方法提供默认实现。Java 8还允许接口包含静态方法。因此,从Java 8开始,接口的成员可以是静态常量,抽象方法,默认方法,静态方法,嵌套类,嵌套接口,嵌套枚举和嵌套批注:
// generic interface with one type parameter T
public interface SomeInterface<T> {
int SOME_CONSTANT = 35; // variable declaration
int abstractMethod(int x, int y); // method declaration
T abstractMethodUsingGenericType(T[] array, int i); // method using type parameter
default int defaultMethod(int x, int y) {
// implementation of method
}
static void main(String[] args) {
// any static method, including main can be included in interface
}
// nested class definition
class NestedClass {
// members of a class
}
// nested interface definition
interface NestedInterface {
// member of an interface
}
// nested enum definition
enum NestedEnum {
OBJECT1,
OBJECT2,
;
// methods, variables and constructors
}
// nested annotation definition
@interface NestedAnnotation {
String attrib1();
}
}
接口中的默认方法和静态方法始终是公共的。现在,由于我们有默认方法(即实现),这意味着在Java中,我们现在还具有行为的多个继承,而不仅仅是类型。
现在,我们有了Java中多重继承的钻石问题。由于我们可以通过默认方法实现行为,因此我们现在可以有一个重复的通用代码,可以在同一接口中的多个默认方法中重复这些代码。为避免这种情况,我们通常将方法的实现分为较小的方法。并且,由于可能不需要在接口外部提供这些方法,因此理想情况下,它们应该是私有的。现在可以使用Java 9来完成,该Java在接口中引入了私有方法。
从Java 9开始的接口中受支持的成员是静态常量,抽象方法,默认方法,静态方法,私有方法,嵌套类,嵌套接口,嵌套枚举和嵌套批注:
// generic interface with one type parameter T
public interface SomeInterface<T> {
int SOME_CONSTANT = 35; // variable declaration
int abstractMethod(int x, int y); // method declaration
T abstractMethodUsingGenericType(T[] array, int i); // method using type parameter
default int defaultMethod(int x, int y) {
// implementation of method
// can call the privateMethod and privateStaticMethod here
}
static void main(String[] args) {
// any static method, including main can be included in interface
// can call privateStatic method here
}
private int privateMethod(int x, int y) {
// private method implementation
}
private static void privateStaticMethod(int x, int y) {
// private method implementation
}
// nested class definition
class NestedClass {
// members of a class
}
// nested interface definition
interface NestedInterface {
// member of an interface
}
// nested enum definition
enum NestedEnum {
OBJECT1,
OBJECT2,
;
// methods, variables and constructors
}
// nested annotation definition
@interface NestedAnnotation {
String attrib1();
}
}
结论
有趣的是,在保持向后兼容性的同时,这些接口的性质多年来已经发生了变化。在Java 8之前,接口的核心宗旨是它只能具有公共和抽象方法。但是,从Java 8开始,接口也可以具有非抽象方法,从Java 9开始,接口也可以具有私有方法。