Why do we need super keyword to call default interface methods?

前端 未结 4 1434
有刺的猬
有刺的猬 2020-12-21 04:40

In the below code when I am having a class implementing two interfaces with same default method signature it ask me to override it. but in the overriden method why I have to

相关标签:
4条回答
  • 2020-12-21 05:13

    Based on comment from @MalteHartwig.

    Direct quote from Java tutorial:

    If two or more independently defined default methods conflict, or a default method conflicts with an abstract method, then the Java compiler produces a compiler error. You must explicitly override the supertype methods.

    Consider the example about computer-controlled cars that can now fly. You have two interfaces (OperateCar and FlyCar) that provide default implementations for the same method, (startEngine):

    public interface OperateCar {
        // ...
        default public int startEngine(EncryptedKey key) {
            // Implementation
        }
    }
    
    public interface FlyCar {
        // ...
        default public int startEngine(EncryptedKey key) {
            // Implementation
        }
    }
    

    A class that implements both OperateCar and FlyCar must override the method startEngine. You could invoke any of the of the default implementations with the super keyword.

    public class FlyingCar implements OperateCar, FlyCar {
        // ...
        public int startEngine(EncryptedKey key) {
            FlyCar.super.startEngine(key);
            OperateCar.super.startEngine(key);
        }
    }
    

    The name preceding super (in this example, FlyCar or OperateCar) must refer to a direct superinterface that defines or inherits a default for the invoked method. This form of method invocation is not restricted to differentiating between multiple implemented interfaces that contain default methods with the same signature. You can use the super keyword to invoke a default method in both classes and interfaces.

    0 讨论(0)
  • 2020-12-21 05:18

    You didn't just override, you have implemented interfaces with same named methods. More exactly, you have implemented two interfaces and you have to resolve diamond problem no matter what code you want to run in AImpl. IDE required of you to override because of diamond hierarchy. Once you have provided code, interA.super is used as a way to navigate to desired code.

    0 讨论(0)
  • 2020-12-21 05:27

    Actually, the use of word super is confusing here. As pointed out by @Basilevs, whenever there is a conflict of default methods from two interfaces implemented by a class, it will result into a compilation error (Fair Enough). To remove this error, the class must provide its implementation of that method, so compiler is not confused any more about which method it will invoke.

    The next thing after resolving the compilation error is how to call the default implementations of the interface by-passing the implementation provided by the class itself. To do that, the method will be called with the name of the direct implemented superinterface that has defined the method.

    In the example above, posted by @Ashraf Mulla, the call interB.super.AImp(); prints "Calling AImp from B" because that is what it is supposed to do as per Java specifications. Interface B is the direct interface which has the implementation for AImp method, so that will be executed.

    To test further, one can also try having third interface which extends both interface A and interface B , which will need to provide its over-ridden implementation of AImp method to overcome compilation error. If a class, implements all the three interfaces (interface A, interface B and interface C extending A and B), then calling interA.super.Aimp, interB.super.Aimp will result in compilation error with the exact description to call with interC.super, that being the direct super interface having the method definition.

    0 讨论(0)
  • Practice class implements 2 interfaces. Namely InterA and InterB. The idiom used specifies which one of the 2 default methods you wish to call. This is because the 2 methods have the same signature.

    However when you override the signature on the Practice class like that:

    package practice;
    
    interface InterA {
    
        public default void AImp() {
            System.out.println("Calling Aimp from interA");
        }
    }
    
    interface InterB {
    
        public default void AImp() {
            System.out.println("Calling Aimp from interB");
        }
    }
    
    public class Practice implements InterA, InterB {
    
        public static void main(String[] args) {
    
            Practice inter = new Practice();
    
            inter.AImp();
    
        }
    
    //    @Override
    //    public void AImp() {
    //
    //        interA.super.AImp();
    //    }
        @Override
        public void AImp() {
            InterA inter = new Practice();
            inter.AImp();
        }
    }
    

    You do not get the same result. You get:

    Exception in thread "main" java.lang.StackOverflowError
    at practice.Practice.AImp(Practice.java:35)
    at practice.Practice.AImp(Practice.java:35)
    at practice.Practice.AImp(Practice.java:35)
    at practice.Practice.AImp(Practice.java:35)
    at practice.Practice.AImp(Practice.java:35)
    at practice.Practice.AImp(Practice.java:35)
    at practice.Practice.AImp(Practice.java:35)
    

    You reference an instance of Practice through the InterA interface, that forces the use of the implemented interface,which will instantiate again Practice and call AImp . This will recursively be repeated until a java.lang.StackOverflowError is thrown.

    0 讨论(0)
提交回复
热议问题