多重继承是面向对象概念的一项功能, 其中一个类可以继承多个父类的属性。当在超类和子类中都存在具有相同签名的方法时, 就会出现问题。调用该方法时, 编译器无法确定要调用哪个类方法, 甚至无法确定哪个类方法具有优先级。
为什么Java不支持多重继承?
考虑下面的Java代码。它显示错误。
// First Parent class
class Parent1
{
void fun()
{
System.out.println( "Parent1" );
}
}
// Second Parent Class
class Parent2
{
void fun()
{
System.out.println( "Parent2" );
}
}
// Error : Test is inheriting from multiple
// classes
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.钻石问题:
下面的Java程序在运行时会引发编译器错误。如果在其他语言(例如C ++)中允许使用多重继承, 则会导致钻石问题。
GrandParent
/ \
/ \
Parent1 Parent2
\ /
\ /
Test
// A Grand parent class in diamond
class GrandParent
{
void fun()
{
System.out.println( "Grandparent" );
}
}
// First Parent class
class Parent1 extends GrandParent
{
void fun()
{
System.out.println( "Parent1" );
}
}
// Second Parent Class
class Parent2 extends GrandParent
{
void fun()
{
System.out.println( "Parent2" );
}
}
// Error : Test is inheriting from multiple
// classes
class Test extends Parent1, Parent2
{
public static void main(String args[])
{
Test t = new Test();
t.fun();
}
}
输出:
Error :
prog.java:31: error: '{' expected
class Test extends Parent1, Parent2
^
1 error
从代码中, 我们可以看到:使用Test对象调用fun()方法会导致复杂性, 例如调用Parent1的fun()还是Child的fun()方法。
因此, 为了避免此类麻烦, Java不支持类的多重继承。
2.简单性–Java使用类不支持多重继承, 因此处理由于多重继承而导致的复杂性非常复杂。它在各种操作(例如强制转换, 构造函数链接等)期间都会产生问题, 并且最重要的原因是, 在实际上我们需要多重继承的场景很少, 因此最好省略它以使事情简单明了。
上述问题如何处理默认方法和接口?
Java 8支持默认方法, 其中接口可以提供方法的默认实现。一个类可以实现两个或多个接口。如果两个已实现的接口都包含具有相同方法签名的默认方法, 则实现类应显式指定要使用的默认方法, 或者应重写默认方法。
// A simple Java program to demonstrate multiple
// inheritance through default methods.
interface PI1
{
// default method
default void show()
{
System.out.println( "Default PI1" );
}
}
interface PI2
{
// Default method
default void show()
{
System.out.println( "Default PI2" );
}
}
// Implementation class code
class TestClass implements PI1, PI2
{
// Overriding default show method
public void show()
{
// use super keyword to call the show
// method of PI1 interface
PI1. super .show();
// use super keyword to call the show
// method of PI2 interface
PI2. super .show();
}
public static void main(String args[])
{
TestClass d = new TestClass();
d.show();
}
}
输出如下:
Default PI1
Default PI2
如果从” TestClass”中删除默认方法的实现, 则会出现编译器错误。看到这个进行样品运行。
如果通过接口有菱形, 则没有任何中间接口提供根接口的实现是没有问题的。如果他们提供实现, 则可以使用super关键字按上述方式访问实现。
// A simple Java program to demonstrate how diamond
// problem is handled in case of default methods
interface GPI
{
// default method
default void show()
{
System.out.println( "Default GPI" );
}
}
interface PI1 extends GPI { }
interface PI2 extends GPI { }
// Implementation class code
class TestClass implements PI1, PI2
{
public static void main(String args[])
{
TestClass d = new TestClass();
d.show();
}
}
输出如下:
Default GPI
如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。
评论前必须登录!
注册