[英]Java Vs C#: Java and C# subclasses with method overrides output different results in same scenario
好! 我有相同的代码用Java和C#编写,但输出不同!
class A
{
public void print()
{
Console.WriteLine("Class A");
}
}
class B : A
{
public void print()
{
Console.WriteLine("Class B");
}
}
class Program
{
static void Main(string[] args)
{
A a = new B();
a.print();
Console.Read();
}
}
输出: A类 。 它在C#中。
但是当在Java中运行相同的代码时,输出是B类 。 这是Java代码:
class A
{
public void print()
{
System.out.println("Class A");
}
}
class B extends A
{
public void print()
{
System.out.println("Class B");
}
}
public class Program{
public static void main(String []args){
A a = new B();
a.print();
}
}
那么,为什么会出现不同的结果呢? 我知道,在Java中,默认情况下所有方法都是虚拟的,这就是Java输出B类的原因。
另一件事是,两种语言都声称它们是由C ++出现或启发的,然后为什么它们显示不同的结果,而两者都有相同的基本语言(Say)。
这条线A a = new B();
实际上呢? 不是B级的持有对象吗? 如果是这样,那么为什么C#显示A类而Java显示B类 ?
注意在采访中询问了上述相同代码的问题。 我回答了输出类B (关于Java),但他说A类将是正确的输出。
谢谢!
在Java中, 非静态方法是虚拟的 ,而在C#中,它们不是虚拟的 。 您需要在print方法中使用virtual
和override
关键字才能在c#中获得相同的行为。
C#中的多态行为:
class A
{
public virtual void print()
{
Console.WriteLine("Class A");
}
}
class B : A
{
public override void print()
{
Console.WriteLine("Class B");
}
}
编辑
回到原始的C#代码,当您在子类及其超类中使用相同的方法签名时,您将在B.print
上获得编译时警告,即:
'print'需要关键字'new',因为它隐藏了方法'MyNamespace.A.print()'
这是一个很好的迹象,表明该方法不会被多态/虚拟调用。 要避免警告(并保留原始的C#行为),在B中您需要添加new
:
public new void print()
这是因为在派生类的C#方法中隐藏,而不是覆盖其基类的方法。 您想要覆盖的方法需要在基础中使用关键字virtual
显式标记,并在派生类中使用关键字override
。
相反,在Java中,默认情况下所有方法都是虚拟的:只需指定相同的签名就足以覆盖。
以下是如何使您的C#程序等效于Java程序:
class A
{
public virtual void print() // Add "virtual"
{
Console.WriteLine("Class A");
}
}
class B : A
{
public override void print()// Add "override"
{
Console.WriteLine("Class B");
}
}
在
A a = new B()
,变量a
保持B
对象,但输出是“A类”! 它不应该叫B
类方法吗?
当您隐藏方法而不是覆盖它时,派生类会保留两个方法 - 基类中的方法和派生类中的方法。 外部呼叫者仍可以访问这两种方法。 他们可以通过使用适当静态类型的对象来决定调用哪两个方法。 这是一个例子:
B b = new B();
b.print(); // Prints "Class B"
((A)b).print(); // Prints "Class A"
使用virtual
/ override
,只能从外部访问一个方法 - 即派生类中的方法。 基类中的方法可以通过派生类的方法访问,但不能由派生类的外部用户访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.