Java 简明教程

Java - Default Methods in Interfaces

Java Default Methods

Java在 Java 8 中的 interfaces 中引入了 default method 实现的新概念。在 Java 8 之前,一个接口只能有 abstract methods。添加了默认方法功能以实现向后兼容性,这样旧接口就可以用于利用 Java 8 的 lambda expression 功能。

例如, ListCollection 接口没有“forEach”方法声明。因此,添加此类方法只会破坏集合框架实现。Java 8 引入了默认方法,这样 List/Collection 接口就可以有 forEach 方法的默认实现,实现这些接口的类不需要实现此方法。

Syntax

以下是 Java 中接口中默认方法的语法 -

public interface vehicle {

   default void print() {
      System.out.println("I am a vehicle!");
   }
}

Java Default Method Example

package com.tutorialspoint;

interface vehicle {
   // default method must have an implementation
   default void print() {
      System.out.println("I am a vehicle!");
   }
}

// implementing class needs not to implement the default method
// of an interface.
public class Tester implements vehicle {
   public static void main(String args[]) {
      Tester tester = new Tester();
      // implementing class can access the default method as its own method
      tester.print();
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

I am a vehicle!

Default Methods in Multiple Inheritance

使用接口中的默认函数,有可能某个类实现了具有相同默认方法的两个接口。以下代码解释了如何解决此歧义。

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!");
   }
}

Example: Overriding default method of interfaces with own implementation

在此示例中,我们创建了两个具有相同默认方法 print() 的接口。由于 Car 类实现了这两个接口,因此必须覆盖默认方法,否则编译器会抱怨存在重复的默认方法。在使用自己的实现覆盖默认方法之后,我们可以轻松地使用 Car 类的 print 方法,如下所示:

package com.tutorialspoint;

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 {
   // overriding the default method will resolve the ambiguity
   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();
   }
}

Example: Calling default method of interfaces

在此示例中,我们创建了两个具有相同默认方法 print() 的接口。由于 Car 类实现了这两个接口,因此必须覆盖默认方法,否则编译器会抱怨存在重复的默认方法。在使用自己的实现覆盖默认方法之后,我们可以轻松地使用 Car 类的 print 方法,如下所示:

package com.tutorialspoint;

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 {
   // use the default method of a interface
   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!

Static Default Methods in Java

从 Java 8 起,接口还可以拥有静态默认方法。这些静态方法充当助手或实用函数,并有助于更好地封装代码。

public interface vehicle {

   default void print() {
      System.out.println("I am a vehicle!");
   }

   static void blowHorn() {
      System.out.println("Blowing horn!!!");
   }
}

Example: Calling static default method of interface

在此示例中,我们创建了两个具有相同默认方法 print() 的接口。由于 Car 类同时实现了这两个接口,因此它必须覆盖该默认方法。在用对接口实现的调用覆盖默认方法之后,我们已按如下所示直接调用了静态方法:

package com.tutorialspoint;

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() {
      // call the Vehicle interface default print method
      Vehicle.super.print();
      FourWheeler.super.print();
	  // call the Vehicle interface static blowHorn method
      Vehicle.blowHorn();
      System.out.println("I am a car!");
   }
}
public class Tester {

   public static void main(String args[]) {
      Vehicle vehicle = new Car();
      vehicle.print();
      // call the Vehicle interface static blowHorn method
	  Vehicle.blowHorn();
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

I am a vehicle!
I am a four wheeler!
Blowing horn!!!
I am a car!
Blowing horn!!!