Javainheritance与C#inheritance
假设Java有这些分层类:
class A { } class B extends A { public void m() { System.out.println("B\n"); } } class C extends B { public void m() { System.out.println("C\n"); } } class D extends C { public static void main(String[] args) { A a = new D(); // am(); // doesn't work B b = new D(); bm(); C c = new D(); cm(); D d = new D(); dm(); } }
这是C#中相同代码的(盲目)复制:
using System; class A { } class B : A { public void M() { Console.WriteLine("B"); } } class C : B { public void M() // I need to use public new void M() to avoid the warning { Console.WriteLine("C"); } } class D : C { public static void Main(String[] args) { A a = new D(); // aM(); // doesn't work B b = new D(); bM(); C c = new D(); cM(); D d = new D(); dM(); } }
当我执行Java代码时,我获得了CCC
而C#返回了BCC
。
对我来说,C#的结果更有意义,因为引用B调用它自己的方法。
- Java设计师决定打印
CCC
而不是BCC
的逻辑是什么? 我的意思是,为什么参考B使用C中的重写方法? 这种方法有什么优势? - 如何像C#一样更改Java代码以打印出
BCC
? 我的意思是,我如何教java调用它使用的确切参考方法? - 如何更改C#代码以打印出
CCC
? 我的意思是,我如何教C#调用重写方法?
这是为虚函数定义:
虚函数或虚方法是一种函数或方法,其行为可以通过具有相同签名的函数在inheritance类中重写。 这个概念是面向对象编程(OOP)的多态部分的一个非常重要的部分。
在C#中,您应该将方法声明为虚拟,以便被覆盖,如MSDN中所示:
- 10.5.3虚拟方法 (来自VS 2003,但它是最新的)
- C#虚拟
由于M
方法不是虚方法,即使b
变量实际上是D
实例,它也会执行bM()
。
在Java中,默认情况下每个方法都是虚拟的,因此当您覆盖方法时(即使没有@Override
注释), bM()
的行为将是inheritancecM()
方法行为的dM()
。
如何像C#一样更改Java代码以打印出BCC? 我的意思是,我如何教java调用它使用的确切参考方法?
你根本无法用Java做到这一点。 C
类中的M
方法将覆盖B
的M
方法。 将final
修饰符添加到B#M
只会使C
或其他B
子项无法覆盖M()
方法。
如何更改C#代码以打印出CCC? 我的意思是,我如何教C#调用重写方法?
将B
类中的M
方法更改为virtual
并在C
类中覆盖它:
class B : A { public virtual void M() { Console.WriteLine("B"); } } class C : B { public override void M() // I need to use public new void M() to avoid the warning { Console.WriteLine("C"); } }
-
在java中,默认情况下所有方法都是虚拟的。 派生类中的方法会覆盖base的方法。 在C#中他们不是。
-
好像你不能这样做。 但是您可以通过将派生类声明为
final
来阻止派生类重写此方法。 -
在基类中使用
virtual
关键字声明此方法,并在派生中使用override
。
Java设计师决定打印CCC而不是BCC的逻辑是什么?
Java默认使方法成为虚拟方法。 在过去,有一种理解认为这是一种很好的做法,而在Java诞生的时候,也许正处于这种理解的顶峰。
这些天 – 虽然很多人坚持这一点 – 但它也有更多的阻力(特别是当虚拟方法打开了类到意外的子类实现选择时)。
(注意:这里没有对错,每种方法都有其优点和缺点。)
如何像C#一样更改Java代码以打印出BCC?
宣布他们是final
。
如何更改C#代码以打印出CCC?
在定义它们的类中声明它们是virtual
或abstract
的(问题中的B
),并在子类中override
。
Java设计师决定打印CCC而不是BCC的逻辑是什么? 我的意思是,为什么参考B使用C中的重写方法? 这种方法有什么优势?
看你从D类对象中调用方法,该对象从C类inheritance了M方法。 引用类型在Java中无关紧要 – 重要的部分是哪个类引用了对象。