2

I'm writing code in which a class implements two interfaces that happens to have two abstract methods with the same name,and two constants with the same identifier:

public class Test implements A,B {

  public void doStuff() {}

  public void make() {}

  public static void main(String[] args) {
    Test t=new Test();
    System.out.println(A.VALUE);
    System.out.println(B.VALUE);
    //System.out.println(Test.VALUE);
    //System.out.println(t.VALUE);
  }

}


interface A {              // implicitly abstract

  int VALUE=11;            // implicitly public static and final

  void doStuff();               // implicitly public and abstract

}


interface B {

  int VALUE=14;

  void make();

  void doStuff();

}

now, I know that as of Java 7, I don't have to worry about name clashing,as far as abstract methods are concerned (right??): I just provide a suitable implementation and I'm good (all methods that share the same name are covered), so I don't get multiple-inheritance-like issues or "diamonds" (which is something I'm going to deal with when I get to Java 8,I suppose).

BUT, as far as constants are concerned, I noticed that if I implement the two interfaces and does not try to access the VALUE field,the compiler doesn't complain.It does,when I uncomment the printing statement.

How is it? is this a normal behaviour? I get an error only when I access those members?

EDIT I mean, why doesn't the compiler warn me of the ambiguity when I try to implement the interfaces?

Luca
  • 1,658
  • 4
  • 20
  • 41
  • 1
    I'm not a Java dev, but I'm pretty sure that `t.Value` call is ambiguous – Matías Fidemraizer Oct 01 '15 at 07:17
  • I guess an easy way to think about it is like this. What is the value of t.Value? – Zymus Oct 01 '15 at 07:19
  • Yes, it is only ambiguous when you are doing something ambiguous. The compiler isn't playing tricks on you, it's normal for it to tell you when you are doing something ambiguous. – Erwin Bolwidt Oct 01 '15 at 07:19
  • @Matías Fidemraizer , u r correct.@Luca this a normal behavior. – Bacteria Oct 01 '15 at 07:19
  • When you are trying to access the variable with class name, obviously it will get confused because both are with same name. If you call it with interface names then there is no prob because it have enough clarity... – Harsha Vardhan Oct 01 '15 at 07:23
  • While implementing interface compiler don't know where you are going to use them, so it cant warn. – Harsha Vardhan Oct 01 '15 at 07:28

5 Answers5

1

now, I know that as of Java 7, I don't have to worry about name clashing,as far as abstract methods are concerned (right??)

That's not something new in Java 7. Since the methods have the same signature in both interfaces, when you implement the method in your class, it implements it for both interfaces. There's no problem there, because there's no ambiguity.

How is it? is this a normal behaviour? I get an error only when I access those members?

Yes, ofcourse that's normal behaviour; it's according to the rules of the Java programming language (it is not a bug in the Java compiler). Just inheriting the constant from two interfaces by itself does not cause ambiguity, so that's why you don't get an error when you just try to do that.

If you try to use the constant without qualification, then the compiler doesn't know which of the two you mean, so it will give you an error.

You'll have to specify from which interface you want to use the constant:

interface A {
    int VALUE = 11;
}

interface B {
    int VALUE = 14;
}

public class Example implements A, B {
    public void method() {
        // Use A.VALUE instead of just VALUE
        System.out.println(A.VALUE);
    }
}
Jesper
  • 202,709
  • 46
  • 318
  • 350
1

All variables in interface are public static. That's why you can access them from any place, event if you don't inherrit that interfaces.

Natalia
  • 4,362
  • 24
  • 25
1

I mean, why doesn't the compiler warn me of the ambiguity when I try to implement the interfaces?

The Java specification allows you to define inheritance from different interfaces with the same name variables. So there is no ambiguity till you access the VALUE. Then you try to access it using simple name the compiler can't decide which one variable it should use and only that situation is ambiguous. Detailed information you can find in Java specification https://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#d5e12665

Quote:

It is possible for an interface to inherit more than one field with the same name. Such a situation does not in itself cause a compile-time error. However, any attempt within the body of the interface to refer to any such field by its simple name will result in a compile-time error, because such a reference is ambiguous.

Scorpio
  • 2,309
  • 1
  • 27
  • 45
0

While implementing interface compiler don't know where you are going to use them, so it cant warn. Consider this scenario. There are three classes which are inheriting these interfaces... "public class Test implements A,B" "public class Test1 implements A" "public class Test2 implements B" In this we can't skip VALUE variable from any interface, because it is mandatory in three classes. If it through error while creating interfaces then you may not able to achieve this scenario.

Harsha Vardhan
  • 411
  • 1
  • 7
  • 16
0

In your Example

interface A {              
  int VALUE=11;           
  void doStuff();               
}

interface B {
  int VALUE = 14;
  void make();
  void doStuff();
}

The variables which are defined in the interfaces are treated as public static final variables. Hence as static variables are class level variables, Which are available through out the class and those can be accessed by class name itself.

In the example above interface A and B are having public static final VALUE variables. And the A interface variable assigned with the value of 11, and B interface assigned with the value of 14.

The complete implementation for A and B interfaces is class Test.

Here class Test implements A,B

By default all properties and behaviors are available in the Test class. But in this case, the VALUE variable is a static and remaining methods are instance methods. Since the scope of the static variables are class level and the memory allocation for the static variables are different compared to instance variables and instance methods.

Hence the scope is different (At class Level), So that there is no chance of diamond problem in this. The code compiles fine and Out put is 11 12 respectively.

Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164