解决Java多重继承中的冲突
一个类可以在Java实现多个接口,但是如果实现的多个默认接口具有相同签名的默认方法呢?然后在实现类中,将从几个父接口调用哪些默认实现。
Java 8 设计人员一直在考虑这种冲突,并为此类场景指定了解决规则。现在让我们看看潜在的冲突场景以及Java 8 中为避免它们而制定的解决规则。
继承的默认方法的冲突解决规则按优先顺序如下
- 规则 1:类的优先级高于接口
- 规则 2:派生接口或子接口比继承层次结构中更高的接口具有更高的优先级
- 规则 3:如果规则 1 和规则 2 无法解决冲突,则实现类必须专门覆盖并提供具有相同方法定义的方法。
现在让我们一一讨论,以了解规则的内部工作流。
执行:
Rule 1 Classes take higher precedence than interfaces
例子
Java
// Java Program to illustrate
// classes take higher precedence than interfaces
// Importing input output classes
import java.io.*;
// Interface 1
interface A {
public default void m1()
{
System.out.println("m1 method of interface m1");
}
}
// Interface 2
interface B {
public default void m1()
{
System.out.println("m1 method of interface B");
}
}
// Helper class
class D {
// Main driver method
public void m1()
{
// Print statement when m1() of classD is called
System.out.println("method of class D");
}
}
// Main class
// It is implementing both the interfaces A and B
class C extends D implements A, B {
// Main driver method
public static void main(String args[])
{
// Creating an object of this class
// in the mai() method
C c = new C();
// Calling the method over the object created
// to illustrate Classes take higher precedence
// than interfaces
c.m1();
}
}
Java
// Java Program to illustrate Derived interfaces or
// sub-interfaces take higher precedence than the interfaces
// higher-up in the inheritance hierarchy
// Interface 1
interface A {
// Method of Interface 1
public default void m1()
{
// Execution command whenever
// interface 1 is called
System.out.println("m1 method of A");
}
}
// Interface 2
// This interface is extending above interface
interface B extends A {
// Method of Interface 1
public default void m1()
{
// Execution command whenever
// interface 2 is called
System.out.println("m1 method of B");
}
}
// Main class
// Which is implementing Interface 2
class C implements B {
// Main driver method
public static void main(String args[])
{
// Creating an object of this class
// in the main method
C c = new C();
// Calling method over class object
// created above to illustrate sub-interface
// has higher precedence
c.m1();
}
}
Java
// Java Program to in which implementing class
// has to specifically override and provide a method
// with the same method definition
// to resolve the conflice
// Importing input output classes
import java.io.*;
// Interface 1
interface A {
// m1() method of Interface 1/A
public default void m1()
{
System.out.println("m1 method of interface m1");
}
}
// Interface 2
interface B {
// m1() method of Interface 2/B
public default void m1()
{
System.out.println("m1 method of interface B");
}
}
// Main Class
// This class implements both the interfaces
class C implements A, B {
// Method 1
// m1() method of class C (This class)
public void m1()
{
// Super keyword called over m1() method
// for interface 2/B
B.super.m1();
}
// Method 2
// Main driver method
public static void main(String args[])
{
// Creating an object of this class
// in the main() method
C c = new C();
// Caliing the method 'm1()'
// over the class object
// in the main method()
c.m1();
}
}
输出:
method of class D
输出说明:
由于类 C 从接口 A、接口 B 和超类 C 继承默认方法 m1()。如果在类 C 中调用 m1() 方法,则执行超类 C 中的实现。
Rule 2 Derived interfaces or sub-interfaces take higher precedence than the interfaces higher-up in the inheritance hierarchy
例子
Java
// Java Program to illustrate Derived interfaces or
// sub-interfaces take higher precedence than the interfaces
// higher-up in the inheritance hierarchy
// Interface 1
interface A {
// Method of Interface 1
public default void m1()
{
// Execution command whenever
// interface 1 is called
System.out.println("m1 method of A");
}
}
// Interface 2
// This interface is extending above interface
interface B extends A {
// Method of Interface 1
public default void m1()
{
// Execution command whenever
// interface 2 is called
System.out.println("m1 method of B");
}
}
// Main class
// Which is implementing Interface 2
class C implements B {
// Main driver method
public static void main(String args[])
{
// Creating an object of this class
// in the main method
C c = new C();
// Calling method over class object
// created above to illustrate sub-interface
// has higher precedence
c.m1();
}
}
m1 method of B
输出说明:
由于接口 B 继承自接口 A。两者都有一个具有相同签名的默认方法 m1()。类 C 实现了接口 A 和 B。当在类 C 的实例上调用 m1() 方法时,则调用接口 B 中的实现,因为它是继承层次结构中最低的子/最派生的接口。
Rule 3 In case Rule 1 and Rule 2 are not able to resolve the conflict then the implementing class has to specifically override and provide a method with the same method definition
例子
Java
// Java Program to in which implementing class
// has to specifically override and provide a method
// with the same method definition
// to resolve the conflice
// Importing input output classes
import java.io.*;
// Interface 1
interface A {
// m1() method of Interface 1/A
public default void m1()
{
System.out.println("m1 method of interface m1");
}
}
// Interface 2
interface B {
// m1() method of Interface 2/B
public default void m1()
{
System.out.println("m1 method of interface B");
}
}
// Main Class
// This class implements both the interfaces
class C implements A, B {
// Method 1
// m1() method of class C (This class)
public void m1()
{
// Super keyword called over m1() method
// for interface 2/B
B.super.m1();
}
// Method 2
// Main driver method
public static void main(String args[])
{
// Creating an object of this class
// in the main() method
C c = new C();
// Caliing the method 'm1()'
// over the class object
// in the main method()
c.m1();
}
}
输出:
m1 method of interface B
输出说明:
- 为了获得所需的行为,实现类当然可以从特定的父接口调用特定的默认方法。但是该类仍然需要覆盖默认方法来解决冲突并调用它。
- 类 C 继承自上例中的接口 A & B,所有接口都有默认的 m1() 实现 ()。由于所有 A & B 接口都是 C 的父接口,因此它们在层次结构的同一级别,并且 C 还必须在自己的 () 上实现 m1() 方法。
Note: Inside Class C’s implementation of print() method it should invoke the specific implementation of interface A or B. For this Java 8 has a special syntax as follows:
.super
In this case m1() method in class C will invoke m1() method of B, its parent, like this – B.super.m1()