Java - 接口中的默认方法
Java 默认方法
Java 在 Java 8 中引入了接口中 default method 实现的新的概念。在 Java 8 之前,interface 只能包含 abstract methods。为了向后兼容性添加了 default method 功能,以便旧的接口能够利用 Java 8 的 lambda 表达式功能。
例如,List 或 Collection 接口中没有 'forEach' 方法声明。因此,添加此类方法将破坏 collection framework 的实现。Java 8 引入了 default method,使得 List/Collection 接口可以为 forEach 方法提供默认实现,而实现这些接口的 class 无需实现它。
语法
以下是在 Java 中 interface 的 default method 语法 -
public interface vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
Java 默认方法示例
package com.;
interface vehicle {
// default method 必须有实现
default void print() {
System.out.println("I am a vehicle!");
}
}
// 实现类无需实现 interface 的 default method。
public class Tester implements vehicle {
public static void main(String args[]) {
Tester tester = new Tester();
// 实现类可以将 default method 作为自己的方法访问
tester.print();
}
}
让我们编译并运行上述程序,这将产生以下结果 −
I am a vehicle!
多重继承中的默认方法
接口中的默认方法可能导致一个 class 实现两个具有相同默认方法的接口。以下代码说明了如何解决这种歧义。
public interface vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
public interface fourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
第一种解决方案是创建一个自己的方法来覆盖默认实现。
public class car implements vehicle, fourWheeler {
public void print() {
System.out.println("I am a four wheeler car vehicle!");
}
}
示例:使用自己的实现覆盖接口的默认方法
在这个示例中,我们创建了两个具有相同默认方法 print() 的接口。由于 Car class 实现了两个接口,因此必须覆盖默认方法,否则编译器会因为重复的默认方法而报错。使用自己的实现覆盖默认方法后,我们可以轻松使用 Car class 的 print 方法,如下所示:
package com.;
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
// 覆盖默认方法将解决歧义
public void print() {
System.out.println("I am a four wheeler car vehicle!");
}
}
public class Tester {
public static void main(String args[]) {
Car car = new Car();
car.print();
}
}
让我们编译并运行上述程序,这将产生以下结果 −
I am a four wheeler car vehicle!
第二种解决方案是使用 super 调用指定接口的默认方法。
public class car implements vehicle, fourWheeler {
public void print() {
vehicle.super.print();
}
}
示例:调用接口的默认方法
在这个示例中,我们创建了两个具有相同默认方法 print() 的接口。由于 Car class 实现了两个接口,因此必须覆盖默认方法,否则编译器会因为重复的默认方法而报错。使用自己的实现覆盖默认方法后,我们可以轻松使用 Car class 的 print 方法,如下所示:
package com.;
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
// 使用某个接口的默认方法
public void print() {
FourWheeler.super.print();
}
}
public class Tester {
public static void main(String args[]) {
Car car = new Car();
car.print();
}
}
让我们编译并运行上述程序,这将产生以下结果 −
I am a four wheeler!
Java 中的静态默认方法
从 Java 8 开始,interface 也可以拥有静态默认方法。这些静态方法充当辅助或实用函数,有助于更好地封装代码。
public interface vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
static void blowHorn() {
System.out.println("Blowing horn!!!");
}
}
示例:调用 interface 的静态默认方法
在这个示例中,我们创建了两个具有相同默认方法 print() 的 interface。由于 Car 类实现了两个 interface,因此它必须重写默认方法。在使用对 interface 实现的调用重写默认方法后,我们如以下所示直接调用了静态方法:
package com.;
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
static void blowHorn() {
System.out.println("Blowing horn!!!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
public void print() {
// 调用 Vehicle interface 的默认 print 方法
Vehicle.super.print();
FourWheeler.super.print();
// 调用 Vehicle interface 的静态 blowHorn 方法
Vehicle.blowHorn();
System.out.println("I am a car!");
}
}
public class Tester {
public static void main(String args[]) {
Vehicle vehicle = new Car();
vehicle.print();
// 调用 Vehicle interface 的静态 blowHorn 方法
Vehicle.blowHorn();
}
}
让我们编译并运行上述程序,这将产生以下结果 −
I am a vehicle! I am a four wheeler! Blowing horn!!! I am a car! Blowing horn!!!