📅  最后修改于: 2020-03-22 14:19:39             🧑  作者: Mango
多重继承是面向对象概念的一项功能,其中一个类可以继承多个父类的属性。当在超类和子类中都存在具有相同签名的方法时,就会出现问题。在调用该方法时,编译器无法确定要调用的类方法,甚至无法在调用哪个类方法获得优先级时确定。
// Parent1类
class Parent1
{
void fun()
{
System.out.println("Parent1");
}
}
// Parent2类
class Parent2
{
void fun()
{
System.out.println("Parent2");
}
}
// 报错
class Test extends Parent1, Parent2
{
public static void main(String args[])
{
Test t = new Test();
t.fun();
}
}
输出:
Compiler Error
从代码中,我们看到,使用Test对象调用方法fun()会导致编译器蒙圈,不知调用Parent1的fun()还是Parent2的fun()方法。
1.钻石问题:
GrandParent
/ \
/ \
Parent1 Parent2
\ /
\ /
Test
// 祖父类
class GrandParent
{
void fun()
{
System.out.println("祖父");
}
}
// 父类1
class Parent1 extends GrandParent
{
void fun()
{
System.out.println("Parent1");
}
}
// 父类2
class Parent2 extends GrandParent
{
void fun()
{
System.out.println("Parent2");
}
}
// 报错
class Test extends Parent1, Parent2
{
public static void main(String args[])
{
Test t = new Test();
t.fun();
}
}
从代码中,我们看到:在使用Test对象调用fun()方法时,会引起诸如调用Parent1的fun()或Child的fun()方法之类的困惑。
因此,为了避免此类麻烦,Java不支持类的多重继承。
2.简单性 :Java类不支持多重继承,因此处理因多重继承而导致的复杂性非常复杂。它在各种操作(例如强制转换,构造函数链接等)中产生了问题,并且最重要的原因是,在实际上我们需要多重继承的场景很少,因此最好省略它以使事情简单明了。
// Java展示默认方法
interface PI1
{
// 默认方法
default void show()
{
System.out.println("默认 PI1");
}
}
interface PI2
{
// 默认方法
default void show()
{
System.out.println("默认 PI2");
}
}
class TestClass implements PI1, PI2
{
// 重写
public void show()
{
PI1.super.show();
PI2.super.show();
}
public static void main(String args[])
{
TestClass d = new TestClass();
d.show();
}
}
输出:
默认 PI1
默认 PI2
如果从“ TestClass”中删除默认方法的实现,则会出现编译器错误。
如果通过接口有钻石问题,那么如果没有中间接口提供根接口的实现就没有问题。如果他们提供实现,则可以使用super关键字按上述方式访问实现。
// Java展示默认方法
interface GPI
{
// 默认方法
default void show()
{
System.out.println("默认 GPI");
}
}
interface PI1 extends GPI { }
interface PI2 extends GPI { }
class TestClass implements PI1, PI2
{
public static void main(String args[])
{
TestClass d = new TestClass();
d.show();
}
}
输出:
默认 GPI