Confused about "super" keyword in this Java example
Asked Answered
C

2

6

In this example on java website's tutorial page. Two interfaces define the same default method startEngine(). A class FlyingCar implements both interfaces and must override startEngine() because of the obvious conflict.

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

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

I don't understand why, from FlyingCar, super is used to refer to both versions of startEngine() in OperateCar and FlyCar interfaces. As I understand it, startEngine() was not defined in any super class, therefore shouldn't be referred as resident in one. I also do not see any relationship between super and the two interfaces as implemented in FlyingCar

Candida answered 18/10, 2015 at 6:55 Comment(3)
super by itself means the superclass. FlyCar.super is new in Java 8, and means the implementation in the interface FlyCar.Durango
See #19976987Ical
Why don’t you read that tutorial instead of just extracting the example code?Stollings
A
5

As I understand it, startEngine() was not defined in any super class, therefore shouldn't be referred as resident in one.

Yes it was defined. It's the default implementation, for example:

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

OperateCar.super.startEngine(key) will execute the default implementation.

If there was no default implementation, just an interface method, then the statement wouldn't make sense, as the interface wouldn't contain an implementation, like this:

public interface OperateCar {
    // ...
    int startEngine(EncryptedKey key);
}

I also do not see any relationship between super and the two interfaces as implemented in FlyingCar

Not sure I understand what you're asking. super is a way to call the implementation in the parent interface. Without super, there's just no other way to express that.

Agitate answered 18/10, 2015 at 7:4 Comment(2)
I know there's a default implementation, but do you mean it assumes a default class(super) on which this default implementation was made? It makes logical sense that way. And if there's a default super class, then I can now see the relationship between the two interfaces and super.Candida
@okeyxyz: there is no such thing like a “default super class” and it’s not clear why you think so. InterfaceName.super is the syntax for calling a non-abstract interface method from an implementation class. That’s it. It looks like this because the Java Language designers said so. These non-abstract interface methods are called default methods, because they need that keyword to be marked as non-abstract. That’s to stay compatible with previous language versions where abstract is implied, even if not specified and because the Java Language designers said so.Stollings
W
7

When you have a class implementing multiple interfaces, and those interfaces contains methods with similar method signature (for e.g. your startEngine method).

In order to know which method you are referring to, you do:

yourInterface.super.method();

You can take a look at this link which also addresses your question.

So, you could also do this:

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

Or this:

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

Either way, you have to specify the interface you are calling the method from, if you are simply calling the method from the interface.

However, this particular situation is an example for a reason. What will be more likely to happen is that you will be doing something like this:

public int startEngine(EncryptedKey key) {
    // Custom implemenation...
}

Which is also valid. However, if you have two interfaces with a method that has an identical signature, that might also be a situation where you should have a single parent interface that declares that method, and two child interfaces that extend it:

public interface Car {
    // ...
    default public int startEngine(EncryptedKey key) {
        // Default implementation
};
}

public interface FlyCar extends Car {
    // Methods unique to FlyCar
}

public interface OperateCar extends Car {
    // methods unique to OperateCar
}
Westney answered 18/10, 2015 at 7:5 Comment(1)
Reamrks: Note that the default modifier is only available in Java 8 onwards.Westney
A
5

As I understand it, startEngine() was not defined in any super class, therefore shouldn't be referred as resident in one.

Yes it was defined. It's the default implementation, for example:

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

OperateCar.super.startEngine(key) will execute the default implementation.

If there was no default implementation, just an interface method, then the statement wouldn't make sense, as the interface wouldn't contain an implementation, like this:

public interface OperateCar {
    // ...
    int startEngine(EncryptedKey key);
}

I also do not see any relationship between super and the two interfaces as implemented in FlyingCar

Not sure I understand what you're asking. super is a way to call the implementation in the parent interface. Without super, there's just no other way to express that.

Agitate answered 18/10, 2015 at 7:4 Comment(2)
I know there's a default implementation, but do you mean it assumes a default class(super) on which this default implementation was made? It makes logical sense that way. And if there's a default super class, then I can now see the relationship between the two interfaces and super.Candida
@okeyxyz: there is no such thing like a “default super class” and it’s not clear why you think so. InterfaceName.super is the syntax for calling a non-abstract interface method from an implementation class. That’s it. It looks like this because the Java Language designers said so. These non-abstract interface methods are called default methods, because they need that keyword to be marked as non-abstract. That’s to stay compatible with previous language versions where abstract is implied, even if not specified and because the Java Language designers said so.Stollings

© 2022 - 2024 — McMap. All rights reserved.