作者adrianshum (Alien)
看板java
标题Re: [问题] 一小段java程式转换成C#
时间Fri Aug 21 11:35:45 2015
※ 引述《kisha024 (4545454554)》之铭言:
: 各位好 如果有一小段java程式 如下
: class A{}
: class B extends A{}
: class C extends B{}
: class P{
: int m(B x) {return 1;} }
: class Q extends P{
: int m(A x) {return 2;} }
: class R extends Q{
: int m(C x) {return 3;} }
: class S extends R{
: int m(B x) {return 4;}
: int m(C x) {return 5;} }
: R s = new S();
: System.out.println(s.m(new B())); // 4
: 我把它转换成C# 如下
: public class A { }
: public class B : A { }
: public class C : B { }
: public class P {
: public virtual int m(B x) { return 1; }
: }
: public class Q : P {
: public virtual int m(A x) { return 2; }
: }
: public class R : Q{
: public virtual int m(C x) { return 3; }
: }
: public class S : R{
: public override int m(B x) { return 4; }
: public override int m(C x) { return 5; }
: }
: R s = new S();
: Response.Write(s.m(new B()) ); // 2
: 很明显输出不一样 java输出是4 C#输出是2
: 想请问是我语法转换上错误? 还是有些语法并不能100%转换过去?
: 谢谢
确实答案我不清楚,提供一些方向。
以我所知,Java & C# 的 method overloading 是在 compile time 发生的。
换而言之:
R s = new S();
s.m(new B());
第二行的时候,compiler 会知道要从 R (因为 s 是 R type 的)
下面找出你要 invoke 的 m().
而在R 底下找到的是在 P 下面定义的 m(B)
到这一步,两者还是没分别的。
然後分别在於,C# 直接 invoke 的是 P::m(B),没有经过 virtual table
lookup (就算有 virtual keyword)
Java 则有经过 vtable,所以能根据实际 instance 的 type 找到 S::m(B)
至於为什麽 C# 有这种behavior,我就不清楚了。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 223.19.45.239
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1440128147.A.76F.html