解决默认方法冲突

默认方法

可以为接口方法提供一个默认实现.必须用default修饰符标记这样一个方法.

public interface Comparable<T>{
      default int compareTo(T other){return 0}
}

解决默认方法冲突

如果现在一个接口中将一个方法定义为默认方法,然后又在超类或另一个接口中定义了同样的方法,会发生什么情况?java解决的规则很简单:

  • 超类优先.如果超类提供了一个具体方法,同名而且相同参数类型的默认方法会被忽略,以超类的方法为准.
  • 接口冲突.如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否为默认参数)相同的方法,必须覆盖这个方法来解决冲突

下面看第二条规则,考虑另一个包含getName方法的接口

interface Named{
      default String getName(){
            return getClass.getName() + "_"+hashCode();
      }
}

如果有一个类同时实现了这两个接口会怎样? 其中Person接口也有getName()

class Student implements Person,Named{
      ...
}

类继承Person和Named接口提供的两个不一致的getName方法.并不是从中选择一个,Java编译器会报告一个错误,让程序员来解决这个二义性.只需要在Student类中提供一个getName方法.在这个方法中,可以选择两个冲突方法中的一个.如下所示

class Student implements Person,Named{
      public String getName(){
            return Person.getName();
      }
}

现在假设Named接口没有为getName提供默认的实现:

interface Named{
      String getName();
}

Student类会从Person接口继承默认方法吗?答案是不会,java设计者更强调一致性.两个接口如何冲突并不重要.如果至少有一个接口提供了一个实现,编译器就会报告一个错误,而程序员就必须解决这个二义性.

我们值讨论了两个接口的冲突.现在考虑另外一种情况,一个类扩展了一个超类,同时实现了一个接口,并从超类和接口继承了相同的方法,加入Person是一个类,Student的定义为:

class Student extends Person implements Named{
      ...
}

在这种情况下,只会考虑超类方法,接口的所有默认方法都会被忽略.这就是类优先.

posted @ 2020-09-23 20:18  刘指导  阅读(174)  评论(0编辑  收藏  举报