繁体   English   中英

Java中具有通用元素的继承

[英]Inheritance in Java with generic elements

如果这些空值/变量不是通用元素,我深表歉意,我真的不确定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-> b / c执行从基本AbstrClass继承的方法,由于已经有一个值,因此将其打印出来。
  2. 21.0-> b / c它执行从AbstrClass继承的方法,但其中没有值,因此它给出给定的值21,但为双AbstrClass值,因为在Impl中将其Impl为双Impl值。
  3. 42->我真的不知道。
  4. 63.0->再次从AbstrClass此操作(请参阅问题2),然后从增量方法中添加42,结果为63。

我的推理是正确的,为什么第三个System.out.println结果为42?

这种混乱是由所谓的字段隐藏引起的。 当您在同一继承层次结构中的多个类中具有相同的字段名称时,您将具有多个不同的字段。

因此,存在一个Impl.value2和一个AbstrClass.value,如果在Impl中调用this.value2或super.value2,则会有所不同。

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

将打印63.0

Impl的构造函数中写道:

this.value2 = value2 + value2;

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

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

您的整体推理很好,但并非100%正确

  1. 它在输出value1的基类上调用getValue1 在父类的构造函数中将value1设置为第一个参数传入的值。 Impl的构造函数忽略其第一个参数,并始终传递"Ferdinand"因此超级构造函数
  2. 它在基类上调用getValue2 ,该基类将打印基类的value2 Impl具有相同名称的变量这一事实无关紧要。 您对.0推理是正确的。
  3. 看到答案的基础部分
  4. 也许可以更精确地指定为什么超类中的value2的值会发生变化`

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

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

归结为:

  • 方法可以被覆盖
  • 字段不能被覆盖

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM