1

I'm just learning Java for some research purposes. I have a question about the interface mechanism in Java. I don't know whether it is correct to understand interface as some sort of special abstract class; but I am confused which method "pr(int _i)" is it using when compiled:

public interface A {
    int flagA=0;
    void pr(int _i);
}

And another interface B like this:

public interface B extends A{
    int flagB=0;
    double pr(int _i);
}

And then I realized a class using interfaces A and B:

public class inter1 implements A,B {
    void pr(int _i){...};
    double pr(int _i){...};
}

It cannot be compiled correctly. Here will NOT form an override over interface A when I used interface B. But will the return type be enough to distinguish two methods?

I have already look up Bruce Eckel's Thinking in Java, but nothing helpful was found.

Thank you for your time!

M A
  • 71,713
  • 13
  • 134
  • 174
Henry.L
  • 219
  • 5
  • 14
  • One comment though: `_i` is not typical java naming convention – Eypros Jan 23 '15 at 12:09
  • ===Update 2015-01-27=== I found a way to realize what I want to achieve: Simply speaking I set up a private internal class internalClass1 inter1$internalClass1.class inside Class inter1, which implements B individually: `code` public class inter1 implements A { //Overrides the method pr in interface A void pr(int _i){...}; class internalClass1 implements B{ //Overrides the method pr in interface B double pr(int _i){...}; } }`code` It works for my purpose and hopefully it will help you, too. – Henry.L Jan 27 '15 at 11:39
  • Another related question is:http://stackoverflow.com/questions/7604030/how-can-an-interface-include-a-method-that-references-the-concrete-implementatio – Henry.L Jan 27 '15 at 11:41

4 Answers4

2

Having just a different return type is not sufficient.

This is because the compiler would not know which method to invoke. That's particularly true if any return value is discarded.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 3
    At the JVM level, the return type is part of the signature, and can be overloaded on. This is crucial to the implementation of bridge methods used for return type covariance in Java 5. However, at the Java _language_ level, the return type is not part of the signature. – C. K. Young Jan 23 '15 at 12:09
  • @ChrisJester-Young Indeed that's correct. Why not put as an answer? I've left mine intentionally simple. – Bathsheba Jan 23 '15 at 12:10
  • @ChrisJester-Young, is there any book I can refer to for these sort of questions? Thank you! – Henry.L Jan 23 '15 at 12:11
  • @Bathsheba Because I don't need the rep. :-P Besides, it's a response to your answer. – C. K. Young Jan 23 '15 at 12:15
  • 1
    @Henr.L The only book I can think of that explains this adequately is the _Java Language Specification_. However, it's absolutely not designed to be accessible to Java beginners; it's for people who implement the Java compiler and runtime. – C. K. Young Jan 23 '15 at 12:16
  • 2
    @ChrisJester-Young Thanks, and I saw another person mention the same book below. My deep appreciation. Hopefully I can use that book someday. – Henry.L Jan 23 '15 at 12:23
2

The Java Language Specification section on Requirements in Overriding and Hiding explains how return types should be related when overriding methods:

If a method declaration d1 with return type R1 overrides or hides the declaration of another method d2 with return type R2, then d1 must be return-type-substitutable (§8.4.5) for d2, or a compile-time error occurs.

Section 8.4.5 explains how return types can be substitutable:

A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2 iff any of the following is true:

  • If R1 is void then R2 is void.

  • If R1 is a primitive type then R2 is identical to R1.

  • If R1 is a reference type then one of the following is true:

    • R1, adapted to the type parameters of d2 (§8.4.4), is a subtype of R2.

    • R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9).

    • d1 does not have the same signature as d2 (§8.4.2), and R1 = |R2|.

Therefore, if the method pr's return type is void, the overrided one in interface B must also return a void. If the return type were int, the overrided method must also return an int. For reference types, the return type should be a subtype or convertible to a subtype:

interface A {
   int flagA = 0;

   Number pr(int _i);
}

interface B extends A {
   int flagB = 0;

   Integer pr(int _i);  // compiles fine
}

On the other hand,

interface A {
   int flagA = 0;

   Integer pr(int _i);
}

interface B extends A {
   int flagB = 0;

   Number pr(int _i);  // does not compile
}
M A
  • 71,713
  • 13
  • 134
  • 174
0

Your definition of Interface B will also have an compilation error,

as method pr()[in interface B] implements pr() in interface A , but return type wont be compatible according to Implementing method rules

in Implementing method the return type should be of same type or of any type on which instanceOf operation returns a true value.(covariant types)

Moreover 2 Methods can be distinguished only on following conditions

  • Number of parameters
  • Type of parameters
  • Order of those parameters

hope this helps!

Good luck!

Vihar
  • 3,626
  • 2
  • 24
  • 47
0

You can not write two identical method with only change in return type in same class.

method overloading is having distinct rule that is not included return type (overloaded method can have different number of arguments, type of arguments and order of arguments)

and also your interface will not be compiled because it isn't overriding method in correct way. co-variant type is only applicable in method overriding not in method overloading.

Prashant
  • 2,556
  • 2
  • 20
  • 26