Java 8 default methods and multiple inheritance in-depth parsing

Source: Internet
Author: User

One of the advantages of Java compared to C + +, which I used to talk about, is that there are no more inheritance problems in Java. Because Java sub-class can only inherit (extends) a single parent class, although can implement (implements) multiple interfaces, but the interface is only abstract methods, the method body is empty, there is no concrete method implementation, there will be no method conflict problem.

These are long-term statements, since Java 8 was released this year, the interface can also define methods (default method). The reason to break the previous design in the mouth
Adding a specific approach is to add new functionality to the classes of the existing thousands of Java class libraries, without having to redesign those classes. For example, just in the collection interface
Add default Stream<E> stream() , the corresponding Set and the List interfaces and their subclasses all contain this method, and you do not have to copy this method for each subclass.

This is a compromise design, and the problem is that it introduces multiple inheritance problems for Java. We know that interfaces can inherit interfaces, and classes can inherit classes and implement interfaces. What happens when the inherited class and the implemented interface have the same signature method? This article explores the multiple inheritance of various situations so that you can clearly understand the rules of multiple inheritance in Java.

Interface inherits multiple parent interfaces

Assuming there are three interfaces Interface A, Interface B, Interface C, the inheritance relationship is as follows:

+---------------+         +------------+|  Interface A  |         | Interface B |+-----------^---+         +---^--------+            |                 |                     | | | | +-+------------+--+                       | Interface c|                          +------------+

A, B has the default method for the same signature default String say(String name) , and if interface C does not override this method, the compilation error occurs.

Interface A {Default string Say (string name) {return ' hello ' + Name;}} Interface B {Default string Say (string name) {return "HI" + Name;}} Interface C extends a,b{}

Error message:

C:/lambda/src>javac-j-duser.country=us Com/colobu/lambda/chapter3/multipleinheritance1.javacom/colobu/lambda /chapter3/multipleinheritance1.java:17:error:interface C inherits unrelated defaults for Say (String) from types A and b< C0/>static interface C extends a,b{               ^1 error

We can override this method in the subinterface so that the C compilation does not go wrong:

Interface C extends A,b{default string say (string name) {return "greet" + Name;}}

Note The method signature does not include the return value of the method, which means that the signature of only two methods with different return values is the same. The following code compiles without errors because A B , unlike the default method, C implicitly inherits two default methods.

Interface A {default void say (int name) {}}interface B {default void Say (String name) {}}interface C extends a,b{}

But in some cases, even a different signature method is difficult to distinguish:

Interface A {default void say (int a) {System.out.println ("a");}} Interface B {default void Say (short a) {System.out.println ("B");}} Interface C extends A,b{}static class D implements C {}public static void main (string[] args) {d d = new D (); byte A = 1;d. Say (a); B

Java will choose the most appropriate method, please refer to the Java specification 15.12.2.5

Interface Multilayer Inheritance

Let's look at the problem of multi-layer inheritance. Inheritance relationships such as A2 inherit A1, C inherits A2.

+---------------+ |  Interface A1 | +--------+------+          |                 |                 |        +--------+------+ |  Interface A2 | +-------+-------+         |                 |                 |         +-------+--------+|   Interface C  |+----------------+

Based on our previous knowledge of class inheritance, it is easy to know that C inherits the default method of A2, including the default method that is directly defined, the default method of overriding, and the default method implicitly inherited from the A1 interface.

Interface A {default void say (int a) {System.out.println ("a");} default void Run () {System.out.println ("A.run");}} Interface B extends a{default void say (int A) {System.out.println ("B");} default void Play () {System.out.println ("B.play");}} Interface C extends a,b{}
Multi-layer Multiple inheritance

The above example is also a single-inheritance example, if such as multiple inheritance?

23456789101112131415+---------------+                          |  Interface A1 |                          +--------+------+                                   |                                          |                                          |                                 +--------+------+         +---------------+|  Interface A2 |         |  Interface B  |+-------+-------+         +---------+-----+        |       +---------+---------^              |       |                                  |       |                          +-------+-------++                         |   Interface C  |                         +----------------+

If A2 and B have the same signature method, this is the same as the first example. If you do not want to compile an error, you can override the default method of the parent interface, and you can invoke the default method that specifies the parent interface:

Interface A1 {default void Say (int a) {System.out.println ("A1");}} Interface A2 extends A1 {}interface B {default void Say (int a) {System.out.println ("B");}} Interface C extends A2,b{default void say (int a) {B.super.say (a);}}
More complex multi-layer multiple inheritance
+--------------+               | Interface A1 |               +------+------++                      |      ^+-------+              |               |      +-------+-------+       |      |  Interface A2 |       |      +------------+--+       |                   ^--++      |                       |      |                    +--+------+-----+              |  Interface C  |              +---------------+

Interface A2 inherits A1, interface C inherits A2 and A1. Code as follows,

Interface A1 {default void Say () {System.out.println ("A1");}} Interface A2 extends A1 {default void Say () {System.out.println ("A2");}} Interface C extends A2,a1{}static class D implements C {}public static void main (string[] args) {d d = new D ();d. Say ();

The above code will not compile an error and run the output A2 .

You can see that interface C implicitly inherits the method of the sub-interface, which is the default method of the Subinterface A2.

Class inheritance

If the inheritance relationship type is all classes, there is no problem with multiple inheritance because the class is still single-inherited.

Class and interface promiscuous

What happens when we replace one of the interfaces in the first example with a class?

+-------------+       +-----------+| Interface A |       |  Class B  |+-----------+-+       +-----+-----+            ^-+    +--+-----^                    |    |                         +---+----+-+                       |  Class C |                       +----------+

The following code does not compile an error:

Interface A {default void Say () {System.out.println ("A");}} Static class B {public void Say () {System.out.println ("B");}} Static class C extends B implements a{}public static void Main (string[] args) {c c = new C (); C.say ();//b}

The resulting output B .

As you can see, the subclass inherits the method of the parent class first, inheriting the default method of the interface if the parent class does not have the same signature method.

Conclusion

More complex inheritance relationships can be simplified into the above inheritance relationships.
According to the above example, the following conclusions can be drawn:

      • The class takes precedence over the interface. If a subclass inherits a parent class and the interface has the same method implementation. Then the subclass inherits the method of the parent class
      • A method in a subtype takes precedence over a method in a parent type.
      • If none of the above conditions are met, you must show overwrite/implement its method, or declare it as abstract.

Java 8 Default method and multiple inheritance in-depth parsing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.