My understanding is this. Let's start by looking at a simpler setup. The Second class is abstract and implements two interfaces: Act and React. Both interfaces declare the void read () method without default. In this case, Second inherits several declarations of the same method, without implementation, and the compiler is happy (JLS 8.4.8.4).
interface Act { void read(); } interface React { void read(); } public abstract class Second implements Act, React { }
If one or both of the interface methods are default methods, we get a compiler error (JLS 8.4.8.4, 9.4.1.3), unless Second inherits the abstract read () method from the superclass (JLS 8.4.8.4), as in the following scenario, where Second actually inherits the three read () methods.
interface Act { default void read() {} } interface React { void read(); } abstract class First { abstract void read(); } public abstract class Second extends First implements Act, React { }
In the absence of such a superclass, Second should give an implementation of read (), thereby preventing the inheritance of conflicting methods (JLS 9.4.1.3). Of course, Second should do the same if all the interface methods are abstract, and we do not want to declare the class itself abstract.
If Second gives a concrete implementation of read (), as in the following example, this method does not "apply" to one or the other of the interface methods: it simply overrides and prevents the inheritance of any and all methods of the superinterface with the same signature - more precisely, with the signature , which is the read () signature in the second, is a subtask - as if there was only one such method (JLS 8.4.8.1). (In some cases, the angle may not be possible for the method to simultaneously satisfy all the contracts of the methods that it must override. James Gosling offers a good example of this in section 4.3.2 of his - and colleagues - Java programming language.)
interface Act { void read(); } interface React { void read(); } public class Second implements Act, React { @Override public void read() {} }
Your case is similar.
interface Act { void read(); } abstract class Enact { void read() {} } public class Second extends Enact implements Act { @Override public void read() {} }
The only real difference is that read () in Enact is a specific method (the fact that Enact is abstract doesn't matter), but things don't change much: the declaration in the second overrides both read () in Act and read ( ) in Enact (JLS 8.4.8.1). At the same time, this is a valid implementation of the Act interface, so there is no problem here.
Note that this code will compile even if Second does not override read (): Second inherits read () from Enact, and the inherited method will be considered an equivalent implementation of the law (JLS 8.4.8, 8.4. 8.1, 9.4.1.3).