Home > front end >  How do the overrides happen when attributes are added in an interface?
How do the overrides happen when attributes are added in an interface?

Time:11-05

interface I{
    String s="I"; 
}
class A implements I{ 
    String s="A";
}
class B extends A{
    String s="B"; 
}
class Demo extends B{
    String s="C";
    void print(){
        System.out.print(((A)this).s ((B)this).s ((Demo)this).s ((I)this).s);
}
    public static void main(String args[]){
        new Demo().print();
    }
}

Here it seems interface contained attributes overrides by the other concrete classes. But as interfacces takes attributes as implicitly ginal and static, then how it get overrides?

Result - ABCI

which means interface variable overrides?

CodePudding user response:

Overriding does not happen here. Overriding is not something that fields do. In this case, the s fields declared in the subclasses/implementations of interfaces hide the fields declared in the superclasses and interfaces.

If fields did override each other, you would be seeing C in all four cases, because this is a reference to Demo, and s in Demo is initialised to "C". See also this post to understand the difference.

From the Java Language Specification,

If a class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class.

Note that whether the field is static, or final, or neither, does not matter.

A hidden field can be accessed by using a qualified name if it is static, or by using a field access expression that contains the keyword super or a cast to a superclass type.

"A cast to a superclass type" is exactly what you are doing. That is why you got "A", "B".

The reason why you got "I" from doing ((I)this).s is not specified in this section (IMO it should have said "a cast to a superclass type or a superinterface type").

See this other section of the JLS,

The type of the Primary must be a reference type T, or a compile-time error occurs.

  • ...
  • Otherwise, the identifier names a single accessible member field in type T ...
  • If the field is static:
    • If the field is a non-blank final field, then the result is the value of the specified class variable in the class or interface that is the type of the Primary expression. ...

Here, the type of the primary expression is obviously I, since you cast to it. As a result, you got the value of the field declared in I.

CodePudding user response:

Because that's how variables work in Java; subclasses will just ignore the parent's variable if it has the same name as the subclass's variable, regardless of any static/final modifiers (see @user85421's comment for a reference). It doesn't just apply to interfaces; consider the following code:

class A {
    int name;
}
class B extends A {
    String name;
}

Even though we use two completely different types for the "same variable", there's no compile error. Throw in some modifiers for fun?

class A {
    static final int name = 0;
}
class B extends A {
    String name;
}

Still no compile error.

Now let's try the same thing but with methods:

class A {
    public int getName() { return 1; };
}
class B extends A {
    public String getName() { return ""; }
}

Compile error. The point is, "overriding" is only a concept with methods, parent variable declarations will just be ignored (if there's a name conflict).

  • Related