An implementation of a method that is present in an interface and abstract class in java

I am trying to understand what happens if the method is present in both the abstract class and the interface. Below I have posted a script that gives you a clear idea of ​​what I mean.

interface act { void read(); } abstract class enact { void read() { System.out.println("hello"); } } public class second extends enact implements act { public void read() { // does method read() correspond to Interface or abstract class? } } 

Surprisingly, there is no compilation error when writing this code. Any suggestions would be very helpful.

+5
source share
3 answers

I'm just curious to know if the read () method relates to an interface or an abstract class

Or, not really. It depends on the visible type in the context in which you use it. For instance. do you do

 enact example = new second(); 

or

 act example = new second(); 

Both allow you to compile code:

 example.read(); 

because the read () method is defined both in apparent types and in action. But in both cases, this read () definition, defined in the second class, really matters. This is what is being implemented.

+1
source

I'm not sure what problems you expect, so I will try to show that there are no problems with this scenario.

You call methods from links such as:

 Second sc = new Second();//you should name your classes with upper-case sc.read(); 

and this will lead to the execution of the code from the Second class, since this is the type of object stored in the sc link (this is how polymorphism works - or, to be precise, dynamic binding ).

You can also create an instance of the Second class and pass it to a link of type Act (all types in Java must begin with an uppercase, including interfaces and enumerations), for example

 Act act = sc;// or Act act = new Second(); act.read(); 

Since the read() method is polymorphic (only finite, private, or static methods are not) at runtime, the JVM will look for code to execute in the class, an instance of which is stored in the art interface, since it is an instance of Second code of the read() class from this class will be executed (if you do not override it in this class of code inherited from Enact , an abstract class will be executed).

+1
source

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).

+1
source

Source: https://habr.com/ru/post/1240650/


All Articles