Java8 - 默认方法接口的教程与实例

167 阅读4分钟

在这篇博文中,我们将通过实例介绍默认方法接口的基础知识。

为什么需要缺省方法接口?

默认方法是java 8版本引入的功能之一。在Java 8版本之前,接口只有抽象方法。抽象方法的实现必须由实现该接口的类来提供。如果任何接口代码被发布,我们就不能改变接口结构,如果需要对接口进行任何修改,就会导致实现接口的类出现代码中断。

正如下面的例子所描述的,接口声明包含了没有实现的抽象方法。

class ClassTwo implements MyInterface {  
 public void methodone() {  
 }  
}  
interface MyInterface {  
 public void methodone();  
}  

在上面的例子中,通过实现MyInterface声明了一个类。这样做非常有效。
现在在一个接口中增加一个方法--methodtwo,如下图所示

interface MyInterface {  
 public void methodone();  
 public void methodtwo();  
  
}  

ClassTwo出现了编译错误,并且破坏了功能。类型ClassTwo必须实现继承的抽象方法MyInterface.methodtwo(),解决这个问题的方法是在.NET中提供一个新方法的实现。这就迫使客户在接口改变时扩展他们的功能。这是与类的设计相矛盾的。当你实现了新的方法后,ClassTwo编译成功。

为了避免这种类型的设计问题,在接口中引入了默认方法。默认方法为接口增加了额外的功能,而没有破坏实现它的类的结构。默认方法是向后兼容以前的版本的。

关于default关键字的重要说明

  • default是一个关键字,只在java 8版本的接口中起作用。
  • 接口方法的前缀必须是default关键字
  • 实现类中的默认方法不需要提供实现。
  • 默认方法可以被重写
  • 缺省方法提供了向后的兼容性
  • 这些方法在java中也可以称为defect或virtual方法

接口默认方法示例

methodDefault()是InterfaceDemo的默认方法。在不破坏实现类的结构的情况下,为接口添加了额外的功能。

public class MyClass implements InterfaceDemo {  
 @Override  
 public void methodHeader() {  
  System.out.println("methodHeader Implementation");  
 }  
 public static void main(String[] args) {  
  MyClass myClassObject = new MyClass();  
  
  // call interfaec abstract method  
  myClassObject.methodDefault();  
  // Call Interface abstract method  
  myClassObject.methodHeader();  
 }  
}  
interface InterfaceDemo {  
 // This is default method  
 default void methodDefault() {  
  System.out.println("Default method");  
 }  
 // This is abstract method  
 void methodHeader();  
}  

输出是

Default method  
methodHeader Implementation  

默认方法的继承

正如你所知,java不支持通过扩展类来实现多重继承,这会导致钻石问题,为了实现多重继承,需要使用多个接口。

由于接口中的默认关键字,多重继承会导致方法的模糊性问题。

在下面的代码中,我们定义了两个默认方法名相同的接口,并通过实现多个接口创建了类,如下图所示

interface InterfaceOne {  
    default void method(){  
       System.out.println("InterfaceOne.method()");  
    }  
}  
  
interface InterfaceTwo {  
    default void method(){  
       System.out.println("InterfaceTwo.method()");  
    }  
}  
  
public class ClassOne implements InterfaceOne, InterfaceTwo{  
}  

这段代码出现了编译错误,因为重复的默认方法被命名为一个带有参数()和()的方法被继承自InterfaceTwo和InterfaceOne类型。
修复重复的缺省方法的方法是覆盖缺省方法,如下所示

  
  
public class ClassOne implements InterfaceOne, InterfaceTwo{  
    public void method(){  
        System.out.println("class method");  
     }  
}  

要调用InterfaceOne的默认方法,请在实现的方法中使用带有方法名的超级关键字。

public void method(){  
     InterfaceOne.super.method();      
      
    } 

接口静态方法示例

静态方法类似于接口中的默认方法。它们在接口中添加额外的功能,而不会破坏实现类中的代码。静态方法不能在实现类中覆盖。

public class MyClass implements InterfaeDemo {  
 @Override  
 public void methodHeader() {  
  System.out.println("methodHeader Implementation");  
 }  
 public static void main(String[] args) {  
  MyClass myClassObject = new MyClass();  
  
  // call interfaec abstract method  
  myClassObject.methodDefault();  
  
  // Call Interface abstract method  
  myClassObject.methodHeader();  
  // interface static method is calling  
  InterfaeDemo.methodStatic();  
 }  
  
}  
interface InterfaeDemo {  
 // This is default method  
 default void methodDefault() {  
  System.out.println("Default Method");  
 }  
 static void methodStatic() {  
  System.out.println("Static Method");  
 }  
 // This is abstract method  
 void methodHeader();  
}  

输出是

Default Method  
methodHeader Implementation  
Static Method  

java8中抽象方法和默认接口方法的区别?

接口现在有默认方法和主体。抽象有具体的方法。但两者是不一样的。抽象类有一个构造函数,接口没有构造函数。抽象类用它们来定义结构化的状态。接口增加了默认实现。两者都是为了不同的目的而定义的。

接口中的默认方法和静态方法的区别?

静态方法不能在实现类中被覆盖 默认方法可以在实现类中被覆盖 静态方法可以被实现类中的接口访问,因为这些属于接口。默认方法可以被实现类的对象访问 类和接口包含相同的静态方法名称,但它们没有相互覆盖。