If you overwrite a field in a subclass of a class, the subclass has two fields with the same name(and different type)?

55,542

Solution 1

Member variables cannot be overridden like methods. The number variables in your classes Beta and Gama are hiding (not overriding) the member variable number of the superclass.

By casting you can access the hidden member in the superclass.

Solution 2

Fields can't be overridden; they're not accessed polymorphically in the first place - you're just declaring a new field in each case.

It compiles because in each case the compile-time type of the expression is enough to determine which field called number you mean.

In real-world programming, you would avoid this by two means:

  • Common-sense: shadowing fields makes your code harder to read, so just don't do it
  • Visibility: if you make all your fields private, subclasses won't know about them anyway

Solution 3

When successor has a field with the same name as a superclass's field it is called - Hiding a field

Java's field does not support polymorphism and does not take a field's type into account

class A {
    String field = "A: field";

    String foo() {
        return "A: foo()";
    }
}

class B extends A {
    //B's field hides A's field
    String field = "B: field";

    String foo() {
        return "B: foo()";
    }
}

@Test
public void testPoly() {
    A a = new A();
    assertEquals("A: field", a.field);
    assertEquals("A: foo()", a.foo());

    B b = new B();
    assertEquals("B: field", b.field);
    assertEquals("B: foo()", b.foo());

    //B cast to A
    assertEquals("A: field", ((A)b).field);  //<--
    assertEquals("B: foo()", ((A)b).foo());
}

[Swift override property]

Solution 4

As a workaround, you can use getter methods:

class A {
    private String field = "A: field";

    String getField() {
        return field;
    }
}

class B extends A {
    private String field = "B: field";

    @Override        
    String getField() {
        return field;
    }
}
Share:
55,542
Kiril Kirilov
Author by

Kiril Kirilov

http://careers.stackoverflow.com/fiction

Updated on July 05, 2022

Comments

  • Kiril Kirilov
    Kiril Kirilov almost 2 years

    I have 3 classes:

    public class Alpha {
        public Number number;
    }
    
    public class Beta extends Alpha {
        public String number;
    }
    
    public class Gama extends Beta {
        public int number;
    }
    

    Why does the following code compile? And, why does the test pass without any runtime errors?

    @Test
    public void test() {
        final Beta a = new Gama();
        a.number = "its a string";
        ((Alpha) a).number = 13;
        ((Gama) a).number = 42;
    
        assertEquals("its a string", a.number);
        assertEquals(13, ((Alpha) a).number);
        assertEquals(42, ((Gama) a).number);
    }