Java的单继承多实现问题
程序员文章站
2024-03-18 21:07:58
...
最近突然想到一个老生常谈的问题:为什么Java的类不支持多继承(接口支持的哈)?
抛开高司令不想搞得太复杂的说法,大概答案就是
- 若子类继承的多个父类拥有相同的成员变量,子类在引用该变量时将无法判别使用哪个父类的成员变量。
- 若子类继承的多个父类拥有相同的方法,同时子类并未覆盖该方法(若覆盖,则直接使用子类中该方法),那么调用该方法时将无法确定调用哪个父类的方法。
那么一个类实现了多个接口,就没有这个问题了吗?
在Java 8之前,很容易解释
- 接口定义的变量都是常量,编译时就确定调用关系,使用接口名可以避免歧义。
- 方法调用时始终只会调用实现类的方法,不存在歧义。
不过,Java 8之后接口可以拥有默认方法,一个类实现的多个接口具有相同的默认方法咋办咧?
没办法,只能要求子类做出选择了(重写该方法)。
相关代码证明
/**
* 一个类实现的多个接口具有相同签名的方法
*
* @author Zhou Huanghua
*/
public class T implements A, B {
public static void main(String[] args) {
int i = A.CONSTANT; // 使用T.CONSTANT不能通过编译
A a = new T();
a.m1(); // 打印T#m1
a.m2(); // 打印B#m2
B b = new T();
b.m2(); // 打印B#m2
T t = new T();
t.m2();// 打印B#m2
}
@Override
public void m1() {
System.out.println("T#m1");
}
/**
* 必须重写,否则编译失败
*/
@Override
public void m2() {
// 调用B的方法
B.super.m2();
}
}
interface A {
int CONSTANT = 1;
void m1();
default void m2() {
System.out.println("A#m2");
}
}
interface B {
int CONSTANT = 2;
void m1();
default void m2() {
System.out.println("B#m2");
}
}
/**
* 接口支持多继承,如果有相同的默认方法必须重写
*/
interface C extends A, B {
@Override
default void m2() {
A.super.m2();
}
}