我很抱歉,如果这些空值/变量不是通用元素,我真的不确定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
方法以及为什么结果是什么
我不确定我的推理是否正确:
AbstrClass
继承的方法,并且因为已经存在一个值,所以它打印出一个。 AbstrClass
的方法,但它没有任何值,因此它给出了给定值21,但是作为double,因为它在Impl
中被定义为双倍价值。 AbstrClass
,(参见问题2)的exectues,我们从increment方法中添加42,结果为63. 我的推理是否正确,为什么第三个System.out.println
导致42?
答案 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%的点
getValue1
的基类上调用value1
。 value1
在父类的构造函数中设置为作为第一个参数传入的任何内容。 Impl
的构造函数忽略其第一个参数,并始终传递"Ferdinand"
,因此超级构造函数getValue2
,它打印基类的value2
。 Impl
具有相同名称的变量这一事实无关紧要。您对.0
的推理是正确的。value2
的值改变了答案 2 :(得分:1)
你的推理是正确的。对于第三个输出,调用impl.value2
将获得在实现中声明的value2
,而不是父类。这是因为与方法不同,成员字段访问不会以多态方式解析,而是在编译时解析。换句话说,无论实际运行时o.x
的实际类型如何,字段访问表达式x
都将访问属于用于声明o
的类型的字段o
。 / p>
子类中的value2
被称为隐藏父类中的那个,因为它具有相同的名称。
答案 3 :(得分:1)
归结为:
ie super.foo
将始终引用超类中的字段foo
,即使您在子类中有相同名称的字段。