我正在学习Java,但有两个问题:
A x = new A();
和
A x = new B();
考虑到:
class A
class B extends A
A x = new B();
(A)x.run_function();
假设A和B都具有函数run_function
,将执行哪个函数?
最重要的区别在于对象的静态和动态类型与对象的引用之间。
说B延伸A,C延伸B。
对象的动态类型(新类型中使用的类型)是其实际的运行时类型:它定义了对象的实际方法。
对象引用(变量)的静态类型是编译时类型:它定义或声明可以在变量引用的对象上调用哪些方法。
变量的静态类型应始终与它引用的对象的动态类型相同或为父类型。
因此,在我们的示例中,静态类型为A的变量可以引用动态类型为A,B和C的对象。静态类型为B的变量可以引用动态类型为B和C的对象。静态类型为C的变量只能引用具有动态类型的对象。动态类型C。
最后,在对象引用上调用方法是静态和动态类型之间的微妙而复杂的交互。(如果您不相信我,请阅读有关方法调用的Java语言规范。)
例如,如果A和B都实现方法f(),并且静态类型为A,而动态类型为C,则调用方法Bf():
B extends A, C extends B
public A.f() {}
public B.f() {}
A x = new C(); // static type A, dynamic type C
x.f(); // B.f() invoked
大大简化:首先,使用接收者(类型A)和参数(没有参数)的静态类型来确定该特定调用的最佳匹配(最特定)方法签名,这是在编译时完成的。在这里,这显然是Af()。
然后,在运行时的第二步中,使用动态类型来定位方法签名的实际实现。我们从C类型开始,但是没有找到f()的实现,因此我们上移到B,并且那里有一个与Af()签名匹配的方法Bf()。因此Bf()被调用。
在我们的示例中,我们说方法Bf()覆盖了方法Af()。类型层次结构中覆盖方法的机制称为子类型多态。
假设我有下面的代码... 不管类ImplementTwo是同时实现B和A,还是只实现B,它仍然需要在接口A中实现方法A(),因为接口B扩展了接口A。有什么理由显式地这样做吗 而不只是 ?
问题内容: 我尝试了一些代码,使用XOR在Java中交换两个整数而不使用第三个变量。 这是我尝试的两个交换函数: 这段代码产生的输出是这样的: 我很好奇,为什么这样说: 与这个不同吗? 问题答案: 问题是评估的顺序: 参见JLS第15.26.2节 首先,对左操作数求值以产生一个变量。 如果该评估突然完成,则赋值表达式由于相同的原因而突然完成;右边的操作数不会被评估,并且不会发生赋值。 否则,将保存
问题内容: 今天,我发现了python语言一个有趣的“功能”,这让我感到非常悲伤。 那个怎么样?我以为两者是等同的!更糟糕的是,这是我调试时遇到的麻烦的代码 WTF!我的代码中包含列表和字典,并且想知道我到底怎么把dict的键附加到列表上而又没有调用.keys()。事实证明,这就是方法。 我认为这两个陈述是等效的。即使忽略这一点,我也可以理解将字符串追加到列表的方式(因为字符串只是字符数组),但是
问题内容: 我目前正在尝试了解在自定义类上使用和之间的区别。有许多网站说使用’+’运算符会导致使用特殊方法-到目前为止还不错。 但是,当我运行以下示例时,我得到两个不同的结果。 结果: 现在,据我了解,执行Python时检查/执行int方法-发现没有实现添加int和C对象的实现-返回NotImplemented- 这使Python知道检查对象C并执行其中的代码。 为什么执行代码会导致结果,但是其他
问题内容: 这是我的第一个问题,我开始学习Python。之间有什么区别: 和 在下面的示例中编写时,它显示不同的结果。 和 问题答案: 在中,在将右侧的表达式赋给左侧之前对其求值。因此,它等效于: 在第二个示例中,运行时已更改的值。因此,结果是不同的。