[英]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.