zoukankan      html  css  js  c++  java
  • 解决默认方法冲突

    默认方法

    可以为接口方法提供一个默认实现.必须用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{
          ...
    }
    

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

  • 相关阅读:
    1105 Spiral Matrix (25分)(蛇形填数)
    1104 Sum of Number Segments (20分)(long double)
    1026 Table Tennis (30分)(模拟)
    1091 Acute Stroke (30分)(bfs,连通块个数统计)
    1095 Cars on Campus (30分)(排序)
    1098 Insertion or Heap Sort (25分)(堆排序和插入排序)
    堆以及堆排序详解
    1089 Insert or Merge (25分)
    1088 Rational Arithmetic (20分)(模拟)
    1086 Tree Traversals Again (25分)(树的重构与遍历)
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/13720757.html
Copyright © 2011-2022 走看看