【Java】探究Java实现多接口时同名方法冲突问题

问题由来

今天与朋友们聊天谈到C++的多继承问题,朋友觉得非常麻烦,特别是遇到方法重复的时候。
这时,我突然想到既然Java通过多接口的implement代替了复杂的多继承,那如果两个甚至多个接口存在相同的方法,会被怎样处理呢?

有这样几种想法:

  • A:会爆出CE(编译错误)。
  • B:调用时会爆出RE(运行时异常)。
  • C:会按照编译时类型来指定,否则会报错。
  • D:实现的是先被指定的接口的方法。
  • E:两个接口的方法被“合并”了。

由于大家对Java的研究还是不够深,还是没有一个定论。

为探究设计的Demo

先来看这样一个例子:
首先是有两个接口A和B,各有各的方法(含一个同名的say()方法):

public interface A {
	void say();
	void walk();
}
public interface B {
	void sleep();
	void say();
}

然后,我们设计一个C类来实现A和B两个接口:

public class C implements A, B {
	@Override
	public void say() {
		System.out.println("说话");
	}
	@Override
	public void walk() {
		System.out.println("行走");
	}
	@Override
	public void sleep() {
		System.out.println("睡觉");
	}
}

设计测试与结果分析

	public static void main(String[] args) {
		C c = new C();
		c.say();
	}

运行是正常的,可见不是简单的CE或者RE,排除A、B、C三种想法
然后我们加上新的语句:

		A a = new C();
		a.say();
		B b = new C();
		b.say();

发现均能达到效果。

由于我采用的是记事本编辑+命令行终端运行的方式,所以不便于直接确定say()方法是从哪里继承过来的,这时可以打开Eclipse IDE,找到say(),按住Ctrl,点击Super Implement,可以看到:

  • c的say()来自A。
  • a的say()来自A。
  • b的say()来自B。

但这还不够,我们不能确定D想法是不是靠谱,我们需要做一组对照实验,对照组就是上述的例子,实验组就是在其他都相同的情况下把implement后面的A和B换序。

public class C implements B, A {
	@Override
	public void say() {
		System.out.println("说话");
	}
	@Override
	public void walk() {
		System.out.println("行走");
	}
	@Override
	public void sleep() {
		System.out.println("睡觉");
	}
}

这时,我们发现c的say()指向的是B。
这印证了我们的D思路。

因为Eclipse IDE自身有一些问题,所以我们不能直接相信Eclipse,D与E之间还需要继续探究。

利用javap命令继续分析

在这里插入图片描述
在这里插入图片描述

5.得出结论

由于是接口方法,毕竟不是真正的多继承,还是存在一定的差别的。
下面的内容,先声明——由于我个人对这里的认识也不是很深,所以只讲出自己的看法:

(1)如果是

A a = new C();

或是

B b = new C();

这样两种情况,则依据javap可以看出,重名方法会跟着接口走,毕竟是编译时类型嘛。

(2)如果是

C c = new C();

这种情况,编译时类型和运行时类型相同,都是实现类的话,我认为是会优先“继承”先implement的接口的同名方法,然后实现。此时,这个方法是子类的,它的super是优先implement的接口的public abstract方法。

因此,个人认为,D想法和E想法都有一定的成立理由,原因应该是二者的结合。

感想

  • “书到用时方恨少”,有这样的困惑,还是自己所学不精的代价,以后应该继续深入的学习,有刨根问底的精神去探究问题。
  • 探究精神很可贵,虽不知标准答案,但我们在遇到无法解决的问题时,可以自主的探究求解,得到“实验结论”。

如有错误,欢迎批评指正,谢谢!

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值