在这篇博文中,我们将通过实例介绍默认方法接口的基础知识。
为什么需要缺省方法接口?
默认方法是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中抽象方法和默认接口方法的区别?
接口现在有默认方法和主体。抽象有具体的方法。但两者是不一样的。抽象类有一个构造函数,接口没有构造函数。抽象类用它们来定义结构化的状态。接口增加了默认实现。两者都是为了不同的目的而定义的。
接口中的默认方法和静态方法的区别?
静态方法不能在实现类中被覆盖 默认方法可以在实现类中被覆盖 静态方法可以被实现类中的接口访问,因为这些属于接口。默认方法可以被实现类的对象访问 类和接口包含相同的静态方法名称,但它们没有相互覆盖。