Search code examples
javainheritanceinitializationfield

How to assign a value for inherited field in Java?


I have two classes, Parent and Child with the following codes:

public class Parent {
    public String word;
}

Parent class only contains one public field.

public class Child extends Parent {

//super.word = "Simple field assignment.";
{
    System.out.println(word);
}
String word2 = super.word = "Field assignment.";

{
    System.out.println(word);
    super.word = "Initialization block.";
    System.out.println(word);
}

public Child(){
    super.word="Constructor.";
    System.out.println(word);
}
}

The question I want to ask is why the simple assignment 'super.word = "word"' is not allowed, but the following double assignment is OK. And could somebody specify what is exactly happening in the latter?

Also why is the assignment allowed inside the initialization block?

If I run the following main program:

public class FieldTest {
public static void main (String[] args)
{
    Child c = new Child();
    System.out.println("1: "+c.word);
    System.out.println("2: "+c.word2);
}
}

The results are:

null
Field assignment.
Initialization block.
Constructor.
1: Constructor.
2: Field assignment.

Solution

  • The statement

    super.word = "Simple field assignment.";
    

    outside a constructor, initializer or method is not valid Java syntax. You can initialize a field when declaring it

    public class Parent {
       public String word = "Don't use mutable public fields!"
    }
    

    and modify these in the constructor or initializer of a subclass

    public class Child extends Parent {
       public Child() {
          super();
          this.word = "Don't mutate parent state like this...";
       }
    }
    

    The super keyword in combination with fields is only useful when you are hiding a variable of the superclass:

    public class Child extends Parent {
        public String word = "Only for demonstration purposes - do not hide fields!";
    
        public Child() {
            super.word = "Mutating the hidden field.";
        }
    }
    

    As you can see from the code this is not something that should end up in production - I cannot remember using super.someField once in my career. Use CheckStyle and FindBugs if you are unsure about certain constructs. If you need any hints on solving a concrete inheritance problem keep me posted.

    P.S.: Hiding Fields in the Java Tutorials.