一个类实现多个接口的同名方法会报错吗?

本贴最后更新于 1600 天前,其中的信息可能已经天翻地覆

大家好,我是小刀,今天和大家讨论一下接口实现的两个问题,众所周知,接口是设计模式的基石,所以了解接口的一些实现对理解设计模式,源码都大有裨益!

接口圈真乱

之所以会提出如标题中的问题, 是因为在看 ArrayList 时,发现接口实现好像有点混乱

如上图所示,其实是有两个问题 1. AbstractList 实现了 List 接口, 然后 ArrayList 又实现了 List 接口. 2. Collection 接口中有个 size() 方法, List 接口中也有一个 size() 方法. 如果有某个类同时实现 CollectionList 接口, 会不会报错?

实践出真知

首先,我们能正常使用 ArrayList 说明上面两个问题应该是不成问题的.对于问题 1. 大家纠结的点应该是在于, 对于接口 A, 如果抽象类 B 实现了接口,那么子类 C 在实现接口时,还要不要重写方法

接口 Greet

/**
 * @author lixiang
 * @date 2020/6/16
 **/
public interface Greet {
    /**
     * 加油的接口定义
     */
     void cheer();
}

抽象实现类 AbstractGreet

/**
 * @author lixiang
 * @date 2020/6/18
 **/
public abstract class AbstractGreet implements Greet {
  
}

这里我们看到抽象类实现接口,要不要去重写方法都不会报错但是通用来说, 抽象类的作用就是,要有一个通用的实现,所以一般来说,还是实现方法比较好, 然后再抛一个抽象的具体实现, 如下所示:

/**
 * @author lixiang
 * @date 2020/6/18
 **/
public abstract class AbstractGreet implements Greet {
    /**
     * 加油的接口定义
     */
    @Override
    public void cheer() {
        System.out.println("这里通常会做一些通用的处理,比如资源初始化,赋初值之类的");
        doCheer();
    }

    /**
     * 留给子类去实现
     */
    public abstract void doCheer();
}

真正的子类 TrueGreet

/**
 * @author lixiang
 * @date 2020/6/17
 **/
public class TrueGreet extends AbstractGreet implements Greet {

    /**
     * 留给子类去实现
     */
    @Override
    public void doCheer() {
        System.out.println("加油加油");
    }
}

在这里可以看到,虽然我们也实现了 Greet 接口,但是因为 AbstractGreet 已经实现过了接口,所以这里就不用再实现接口的 cheer 方法, 只需要实现抽象类的 doCheer() 方法就可以了,当然也可以实现

@Override
    public void cheer() {
        super.cheer();
        System.out.println("子类自己的实现");
    }

这样加上自己的实现也是没有问题的,所以说, 像开头 AbstractList 实现了 List 接口后, ArrayList 是不用再实现 List 的接口的, 实现了不重写其中的方法,编译也不会报错, 只能说是让结构更清晰一些. 这里还有一个比较有趣的现象,就是在 idea 中, 要重写方法时, 提示的是覆写抽象类的,而不是接口的,如下图所示:

报错的场景

上面都是正确的,其实有一种报错的场景要注意, 就是当两个不同的接口定义的方法签名不一致的时候(方法名,入参一样,返回值不一样)的时候,对于实现类,就找不到该重写哪个了,就会报错,如下所示

GreetCopy 接口

/**
 * @author lixiang
 * @date 2020/6/17
 **/
public interface GreetCopy {
    /**
     * 加油的接口定义
     */
    String cheer();
}

和最开始我们定义的 Greet 接口不一样的是, 返回值从 voi 改成了 String,

如上图所示, 这样编译都是通不过的, 但是如果签名换成一样的,就不成问题了.

总结

其实在写本文之前,小刀也是对这些实现关系不是很清楚, 这样边实践边写下来就清晰多了.希望大家也能多实践,也如我一直说的,学编程其实就是多实践,多思考. 大家一起加油!

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3186 引用 • 8212 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...