zoukankan      html  css  js  c++  java
  • 组合接口时名字冲突问题

      之前从没注意到实现多个接口可能会存在方法冲突的问题,在《Thinking in Java》中看到一个有趣的例子,其本质是重载和重写的问题,关于重载和重写的概念和区别可参看另一篇文章Java基础一:面向对象的特征。首先看例子:

     1   interface I1 {
     2         void f();
     3     }
     4 
     5     interface I2 {
     6         int f(int i);
     7     }
     8 
     9     interface I3 {
    10         int f();
    11     }
    12 
    13     class C {
    14         public int f(){
    15             return 1;
    16         }
    17     }
    18 
    19     class C2 implements I1,I2{//重载
    20         @Override
    21         public void f() {}
    22 
    23         @Override
    24         public int f(int i) {
    25             return 0;
    26         }
    27     }
    28 
    29     class C3 extends C implements I2{
    30         @Override
    31         public int f(int i) {//重载
    32             return 0;
    33         }
    34     }
    35 
    36     class C4 extends C implements I3{
    37         @Override
    38         public int f() {   //重写
    39             return 0;
    40         }
    41     }
    42 
    43 //    class C5 extends C implements I1{}
    44 //
    45 //    interface I4 extends I1,I3{}
    46 
    47   public static void main(String[] args){
    48         MethodCollision methodCollision = new MethodCollision();
    49         C4 c4 = methodCollision.new C4();
    50         System.out.println(c4.f());//输出0
    51     }

       其中接口I1中存在方法void f(),I2中存在int f(int i),I3中存在int f(),类C中存在int f()的方法。

      C2类实现接口I1和I2,其中实现的方法void f()int f(int i)具有不同的签名,属于重载;

      C3类实现接口I2、继承C,C3实现I2中的int f(int i),并继承C中的int f()方法,它们具有不同的签名,属于重载;

      C4类实现接口I3、继承C,C4实现I3中的int f(),并继承C中的int f()方法,它们具有相同的签名,并且返回值类型也相同,属于重写(从程序输出0可以说明);

      C5类实现接口I1、继承C,理论上,C5类会分别实现和继承I1方法void f()和C方法int f(),它们具有相同的签名,不同的返回值类型,既不是重写,也不能重载,故编译器提示错误;

      I4接口继承I1和I3,同样理论上继承void f()int f(),但既不是重写,也无法重载,编译器报错。


      另一个有趣问题是,我如果将接口I1中的void f()改为int f(),会产生什么效果呢?

     1     interface I1 {
     2         int f();
     3     }
     4 
     5     interface I2 {
     6         int f(int i);
     7     }
     8 
     9     interface I3 {
    10         int f();
    11     }
    12 
    13     class C {
    14         public int f(){
    15             return 1;
    16         }
    17     }
    18 
    19     class C2 implements I1,I2{//重载
    20         @Override
    21         public int f() {
    22             return 0;
    23         }
    24 
    25         @Override
    26         public int f(int i) {
    27             return 0;
    28         }
    29     }
    30 
    31     class C3 extends C implements I2{
    32         @Override
    33         public int f(int i) {//重载
    34             return 0;
    35         }
    36     }
    37 
    38     class C4 extends C implements I3{
    39         @Override
    40         public int f() {   //重写
    41             return 0;
    42         }
    43     }
    44 
    45     class C5 extends C implements I1{}//不重写该函数,继承自C的方法即为实现
    46 
    47     interface I4 extends I1,I3{}
    48 
    49     class C6 implements I4{//I1和I3的方法一样,实现类只实现一个
    50         @Override
    51         public int f() {
    52             return 0;
    53         }
    54     }
    55 
    56     public static void main(String[] args){
    57         MethodCollision methodCollision = new MethodCollision();
    58         C4 c4 = methodCollision.new C4();
    59         System.out.println(c4.f());//0
    60 
    61         C5 c5 = methodCollision.new C5();
    62         System.out.println(c5.f());//1
    63     }

       其中接口I1中存在方法int f(),I2中存在int f(int i),I3中存在int f(),类C中存在int f()的方法。

      C2类实现接口I1和I2,其中实现的方法int f()int f(int i)具有不同的签名,属于重载;

      C3类实现接口I2、继承C,属于重载;

      C4类实现接口I3、继承C,属于重写(从程序输出0可以说明);

      C5类实现接口I1、继承C,C5类会分别实现和继承I1方法int f()和C方法int f(),其与C4类是相同的,它是重写吗?不是,因为其继承自C的函数已经实现了该接口,没有重写(从程序输出1可以说明);

      I4接口继承I1和I3,同时继承I1和I3的int f(),它们具有相同的方法签名和返回值类型,所以I4具有一个int f()(可通过C6实现类看出);

      C6类实现接口I4,具有一个实现函数int f()。

     总结:

    • 类不可以多重继承,接口可以多重继承;
    • 组合接口时,可能会存在方法重载和重写的问题,并且可能会引入代码的混乱,降低代码可读性,故尽量避免这种情况;
    • 通过该例,可以学习继承、接口实现、重载和重写概念,其中一点是类继承的方法也可以作为实现接口的实现方法。
  • 相关阅读:
    LINUX常见服务列表
    xinetd服务管理
    System V启动脚本启动的服务
    linux系统服务
    proc文件系统
    sar网络统计数据
    sar磁盘I/O统计数据
    sar-CPU统计数据
    linux性能监视工具sar
    考试认证
  • 原文地址:https://www.cnblogs.com/shuimuzhushui/p/6864385.html
Copyright © 2011-2022 走看看