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{
          ...
    }
    

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

  • 相关阅读:
    MySQL 操作命令梳理(1)-- 索引
    Linux下对LVM逻辑卷分区大小调整 [针对xfs和ext4文件系统]
    CentOS6 虚拟机安装后,无Iptables配置文件
    Linux系统权限设置
    完整部署CentOS7.2+OpenStack+kvm 云平台环境(2)--云硬盘等后续配置
    完整部署CentOS7.2+OpenStack+kvm 云平台环境(3)--为虚拟机指定固定ip
    Android消息推送怎么实现?
    Android 下拉刷新
    Windows 10 周年更新正式版下载 + win10 快捷键
    markdown编辑器使用建议
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/13720757.html
Copyright © 2011-2022 走看看