使用泛型元素

时间:2017-01-21 13:15:22

标签: java inheritance

我很抱歉,如果这些空值/变量不是通用元素,我真的不确定Java中的术语。

我们获得此代码:

public class AbstrClass <T, S> {
  private T value1;
  protected S value2;

  protected AbstrClass (T value1, S value2) {
    this.value1 = value1;
    this.value2 = value2;
 }

  public T getValue1() {
    return value1;
 }

  public S getValue2() {
    return value2;
}

}

public class Impl extends AbstrClass<String, Double> {

  protected Integer value2;

  public Impl (String value1, int value2) {
    super("Ferdinand", (double) value2);
    this.value2 = value2 + value2;
}

  public void incrementValue2 (Integer value) {
    super.value2 += value;
}

public static void main(String[] args) {

  Impl impl = new Impl("Horst", 21);
  System.out.println(impl.getValue1());
  System.out.println(impl.getValue2());
  impl.incrementValue2(42);
  System.out.println(impl.value2);
  System.out.println(impl.getValue2());
}
}

然后我们被问到如果我们运行代码/ main方法以及为什么结果是什么 我不确定我的推理是否正确:

  1. Ferdinand - &gt; b / c它执行一个从基类AbstrClass继承的方法,并且因为已经存在一个值,所以它打印出一个。
  2. 21.0 - &gt; b / c它表示它继承自AbstrClass的方法,但它没有任何值,因此它给出了给定值21,但是作为double,因为它在Impl中被定义为双倍价值。
  3. 42 - &gt;这个我真的不明白。
  4. 63.0 - &gt;再次来自AbstrClass,(参见问题2)的exectues,我们从increment方法中添加42,结果为63.
  5. 我的推理是否正确,为什么第三个System.out.println导致42?

4 个答案:

答案 0 :(得分:2)

这种混乱是由字段隐藏引起的。如果在同一继承层次结构中的多个类中具有相同的字段名称,则会有多个不同的字段。

所以有一个Impl.value2和一个AbstrClass.value,如果你在Impl中调用this.value2或super.value2会有区别。

System.out.println(((AbstrClass<String,Double>) impl).value2);

将打印63.0

答案 1 :(得分:1)

Impl的构造函数中写道:

this.value2 = value2 + value2;

21的给定输入的含义,value2的值为42
impl.incrementValue2(42);仅影响super类中同名变量。

System.out.println(impl.value2);将打印value2的变量Impl的值 - 在构造函数中设置为42

你的总体推理是好的,而不是100%的点

  1. 它在打印getValue1的基类上调用value1value1在父类的构造函数中设置为作为第一个参数传入的任何内容。 Impl的构造函数忽略其第一个参数,并始终传递"Ferdinand",因此超级构造函数
  2. 它在基类上调用getValue2,它打印基类的value2Impl具有相同名称的变量这一事实无关紧要。您对.0的推理是正确的。
  3. 查看答案的基础部分
  4. 也许更准确地说明为什么超级类value2的值改变了

答案 2 :(得分:1)

你的推理是正确的。对于第三个输出,调用impl.value2将获得在实现中声明的value2,而不是父类。这是因为与方法不同,成员字段访问不会以多态方式解析,而是在编译时解析。换句话说,无论实际运行时o.x的实际类型如何,字段访问表达式x都将访问属于用于声明o的类型的字段o。 / p>

子类中的value2被称为隐藏父类中的那个,因为它具有相同的名称。

答案 3 :(得分:1)

归结为:

  • 方法可以被覆盖
  • 字段无法覆盖

ie super.foo将始终引用超类中的字段foo,即使您在子类中有相同名称的字段。