如何为Java中的继承字段赋值?

时间:2013-06-05 10:39:50

标签: java inheritance initialization field

我有两个类,Parent和Child,代码如下:

public class Parent {
    public String word;
}

父类只包含一个公共字段。

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

我想问的问题是为什么不允许使用简单的赋值'super.word =“word”',但是下面的双重赋值是正常的。有人可以指出后者究竟发生了什么吗?

为什么在初始化块内允许赋值?

如果我运行以下主程序:

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

结果是:

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

5 个答案:

答案 0 :(得分:2)

声明

super.word = "Simple field assignment.";

在构造函数之外,初始化程序或方法不是有效的Java语法。您可以在声明字段时初始化字段

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

并在子类的构造函数或初始值设定项中修改它们

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

super关键字与字段组合仅在隐藏超类的变量时才有用:

public class Child extends Parent {
    public String word = "Only for demonstration purposes - do not hide fields!";

    public Child() {
        super.word = "Mutating the hidden field.";
    }
}

正如你从代码中看到的那样,这不应该是最终生产的东西 - 我不记得在我的职业生涯中曾经使用super.someField。如果您不确定某些结构,请使用CheckStyle和FindBugs。如果您需要有关解决具体继承问题的任何提示,请告诉我。

P.S。:Hiding Fields in the Java Tutorials

答案 1 :(得分:0)

如果您指的是注释掉的行

super.word =  "Simple field assignment.";

该行出错,因为它是语句直接在类体内发生“裸”。在那个位置只允许声明。实例初始化程序就是这样一个例子。

在另一点上,您对super的使用完全是多余的。您可以删除它而不会影响语义,或者您可以使用this代替相同的结果。

答案 2 :(得分:0)

尝试将child的定义更改为以下

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

即。在块内放置super.word =“简单字段赋值” - 所有非声明的代码都必须进入初始化块。请参阅here

答案 3 :(得分:0)

不允许第一个赋值,因为它直接在类的内部,而另一个在一个块内,所以没关系。

要回答第二个问题,让我们看看发生了什么:

  1. Child正在实例化,因此第一个块被执行,打印word,尚未初始化,因此它是null
  2. 属性word2的值为word,其值为Field assignment.,它们都包含此字符串。
  3. word已打印:Field assignment.
  4. word的值为Initialization block.
  5. word已打印:Initialization block.
  6. Child的构造函数被调用,word被赋予值Constructor.并正在打印。
  7. 正在打印word的值:Constructor.
  8. 正在打印word2的值:Field assignment.

答案 4 :(得分:0)

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

这是输出:

hello from Static
hello from main
This is my object block

只要将类加载到JVM中,就会执行静态块。而在创建所述对象的实例时,将运行对象块或构造函数块。

欲了解更多信息,请访问

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