Java 8 界面变化包括界面中的静态方法和默认方法.在 Java 8 之前,我们只能在界面中有方法声明,但从 Java 8 开始,我们可以在界面中有 默认方法和 静态方法。
Java 8 接口
Designing interfaces have always been a tough job because if we want to add additional methods in the interfaces, it will require change in all the implementing classes. As interface grows old, the number of classes implementing it might grow to an extent that it's not possible to extend interfaces. That's why when designing an application, most of the frameworks provide a base implementation class and then we extend it and override methods that are applicable for our application. Let's look into the default interface methods and static interface methods and the reasoning of their introduction in Java 8 interface changes.
Java 界面默认方法
要在 java 接口中创建默认方法,我们需要使用**default**
密码与方法签名。
1package com.journaldev.java8.defaultmethod;
2
3public interface Interface1 {
4
5 void method1(String str);
6
7 default void log(String str){
8 System.out.println("I1 logging::"+str);
9 }
10}
请注意,log(String str)是Interface1
中的默认方法. 现在,当一个类将实施Interface1时,不需要为默认接口方法提供实现。 此功能将帮助我们以额外的方法扩展接口,我们只需要提供默认实现。 假设我们有另一个接口有以下方法:
1package com.journaldev.java8.defaultmethod;
2
3public interface Interface2 {
4
5 void method2();
6
7 default void log(String str){
8 System.out.println("I2 logging::"+str);
9 }
10
11}
我们知道Java不允许我们扩展多个类,因为它会导致钻石问题
,编译器无法决定使用哪种超级类的方法。使用默认方法,钻石问题也会发生在界面上,因为如果一个类正在实施Interface1和Interface2并且不执行共同的默认方法,编译器无法决定选择哪一种。扩展多个界面是Java的一个组成部分,你会发现它在Java核心类以及大多数企业应用程序和框架中。所以要确保这个问题不会发生在界面上,它被强制提供界面共同的默认方法的实现。因此,如果一个类正在实施上述两种界面,它将需要为‘log()’方法提供实施,否则编译器将破坏编译错误的简单时间。
1package com.journaldev.java8.defaultmethod;
2
3public class MyClass implements Interface1, Interface2 {
4
5 @Override
6 public void method2() {
7 }
8
9 @Override
10 public void method1(String str) {
11 }
12
13 @Override
14 public void log(String str){
15 System.out.println("MyClass logging::"+str);
16 Interface1.print("abc");
17 }
18}
關於 java 界面默認方法的重要點:
- 联合国 Java 接口默认方法将帮助我们扩展接口,而不必担心中断执行类.
- Java接口默认方法可以缩小接口和抽象类之间的差异.
- Java 8 接口默认方法将帮助我们避免工具类,例如所有收藏类方法都可以在接口本身中提供.
- Java接口默认方法会帮助我们去除基础执行类,我们可以提供默认执行,并且执行类可以选择哪一个来覆盖.
- 在界面中引入默认方法的一个主要原因是增强Java 8中的Collections API以支持lambda表达式. (
(英语). 如果等级体系中的任何一类都有一个具有相同签名的方法,那么默认的方法就变得无关紧要了. 默认方法不能覆盖
java.lang
方法。 目标。 推理非常简单,因为Object是所有java班的基班. 因此,即使我们把Object类方法定义为接口中的默认方法,也会因为Object类方法总是被使用而变得无用. 所以为了避免混淆,我们不能有超越对象类方法的默认方法. ( (英语). 7. Java接口默认方法也被称为"维权方法"或"虚拟扩展方法". (_) (英语)
Java 接口静态方法
Java 界面静态方法与默认方法相似,但我们不能将它们排列在实现类中。
1package com.journaldev.java8.staticmethod;
2
3public interface MyData {
4
5 default void print(String str) {
6 if (!isNull(str))
7 System.out.println("MyData Print::" + str);
8 }
9
10 static boolean isNull(String str) {
11 System.out.println("Interface Null Check");
12
13 return str == null ? true : "".equals(str) ? true : false;
14 }
15}
现在让我们来看看一个具有 isNull() 方法的实现类别,其实现情况不佳。
1package com.journaldev.java8.staticmethod;
2
3public class MyDataImpl implements MyData {
4
5 public boolean isNull(String str) {
6 System.out.println("Impl Null Check");
7
8 return str == null ? true : false;
9 }
10
11 public static void main(String args[]){
12 MyDataImpl obj = new MyDataImpl();
13 obj.print("");
14 obj.isNull("abc");
15 }
16}
请注意, isNull(String str)
是一种简单的类方法,它不会超越界面方法. 例如,如果我们将 @Override 注释 添加到 isNull() 方法,则会导致编译器错误。
1Interface Null Check
2Impl Null Check
如果我们将界面方法从静态到默认,我们将获得以下输出。
1Impl Null Check
2MyData Print::
3Impl Null Check
Java 界面静态方法仅可见于界面方法,如果我们从MyDataImpl
类中删除 isNull() 方法,我们将无法将其用于MyDataImpl
对象,然而,与其他静态方法一样,我们可以使用界面静态方法使用类名称。
1boolean result = MyData.isNull("abc");
关于 Java 界面静态方法的关键点:
- Java 界面静态方法是界面的一部分,我们不能用它来实现类对象.
- Java 界面静态方法是提供实用方法的好,例如 null 检查,集合排序等.
- Java 界面静态方法有助于我们通过不允许实现类对它们进行排序而提供安全性
- 我们不能为 Object 类方法定义界面静态方法,我们会得到编译器错误,如
这个静态方法不能将实例方法从 Object 隐藏
。这是因为它在 Java 是不允许的,因为 Object 是所有类的基础类,我们不能有一个类级静态方法和另一个具有相同签名的实例方法 5.我们可以使用
Java 功能界面
在我完成这篇文章之前,我想简要介绍功能界面。一个具有完全一个抽象方法的界面被称为功能界面。 一个新的注释 @FunctionalInterface 已经被引入,以标记一个界面为功能界面。 @FunctionalInterface 注释是避免在功能界面中偶然添加抽象方法的一种设施。 这是可选的,但很好的做法使用它。 功能界面一直在等待,并且在 Java 8 中很受欢迎,因为它允许我们使用 lambda 表达式来实时化它们。 一个新的包 java.util.function
与一堆功能界面被添加,以为 lambda 表达式和方法参考提供目标类型。 我们将在未来的帖子中研究功能界面和 lambda 表达式。