Pertti
Pertti

Reputation: 13

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.

Upvotes: 1

Views: 4940

Answers (5)

Jens Birger Hahn
Jens Birger Hahn

Reputation: 917

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.

Upvotes: 2

Talha
Talha

Reputation: 699

    class Check {
    //static block
    static {
        System.out.println("hello from Static");
    }
    //object block

    {
        System.out.println("This is my object block");
    }

    public static void main(String args[]) {
        System.out.println("hello from main");
        Check obj = new check();
    }
}

this is the Output:

hello from Static
hello from main
This is my object block

The static block is executed whenever the class is loaded into the JVM. Whereas the object block or constructor block will be run when you create an instance of said object.

For more info please visit

http://www.jusfortechies.com/java/core-java/static-blocks.php http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

Upvotes: 0

Djon
Djon

Reputation: 2260

The first assignment is not allowed because it is directly inside of the class, wherease the other one is within a block, so it's ok.

To answer the second question, let's see what is happening:

  1. Child is being instantiated, so the first block is executed, printing word, which hasn't been initialized, so it's null.
  2. Attribute word2 is given the value of word, which has been given the value Field assignment., they both contains this string.
  3. word is printed: Field assignment.
  4. word is given the value Initialization block.
  5. word is printed: Initialization block.
  6. Child's constructor is called, word is given the value Constructor. and is being printed.
  7. The value of word is being printed: Constructor.
  8. The value of word2 is being printed: Field assignment.

Upvotes: 0

selig
selig

Reputation: 4844

Try changing the definition of child to the following

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);
}
}

i.e. place super.word = "Simple field assignment" inside the block - all code that isn't a declaration has to go inside an initialiser block. See here.

Upvotes: 0

Marko Topolnik
Marko Topolnik

Reputation: 200206

If you are referring to your commented-out line

super.word =  "Simple field assignment.";

that line is in error because it is a statement occuring "naked" directly within the class body. In that position only declarations are allowed. An instance initializer is such an example.

On a separate point, your usage of super is entirely superfluous. You can delete it with no effect on the semantics or you can use this instead, again with the same result.

Upvotes: 0

Related Questions