[英]Regarding C# OOPS virtual/override keyword usage
只看這個程序
class A
{
public void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public void Foo() { Console.WriteLine("B::Foo()"); }
}
class Test
{
static void Main(string[] args)
{
A a;
B b;
a = new A();
b = new B();
a.Foo(); // output --> "A::Foo()"
b.Foo(); // output --> "B::Foo()"
a = new B();
a.Foo(); // output --> "A::Foo()"
}
}
1)如何分類可以具有同名的功能。 當類b進入A時,類A具有foo()函數,而類b具有foo()函數。當類b擴展a時,通過繼承,類b獲得了稱為foo()的函數。 為什么上面的代碼運行沒有任何錯誤?
2)
a = new B();
a.Foo(); // output --> "A::Foo()"
a = new B()是什么意思?
我們是否在創建B的實例(如果是),那么當我們編寫a.Foo()時,應該調用b類的foo()函數,但是卻調用了a類的foo()函數,為什么?
當我們添加virtual / override關鍵字時,將調用類b的foo()函數。
class A
{
public virtual void Foo() { Console.WriteLine("A::Foo()"); }
}
class B : A
{
public override void Foo() { Console.WriteLine("B::Foo()"); }
}
class Test
{
static void Main(string[] args)
{
A a;
B b;
a = new A();
b = new B();
a.Foo(); // output --> "A::Foo()"
b.Foo(); // output --> "B::Foo()"
a = new B();
a.Foo(); // output --> "B::Foo()"
}
}
所以請解釋一下幕后發生的事情。 謝謝
當類b擴展a時,通過繼承類b獲得了名為foo()的函數。 為什么上面的代碼運行沒有任何錯誤?
因為B
中的成員只是將成員隱藏在A
。
a = new B()是什么意思?
由於B
實現A
,因此您將創建B
的實例,並在其他任何地方使用它時將其鍵入為A
這就是為什么要調用類A
的函數而不是B
。
當我們添加virtual / override關鍵字時,將調用類b的foo()函數。
之所以在這里調用B
是因為,實際上它覆蓋了A
的功能。
當您聲明具有相同名稱的方法時,它將隱藏該方法。
如果要調用繼承的方法,可以執行以下操作:
var b = new B();
var casted = (A)b;
casted.Foo(); // will call A.Foo
如果你的目的是覆蓋的功能Foo
中B
,那么你可以使用new
內關鍵字B
:
public new void Foo() { ... }
或者按照您的說明使用virtual
和override
。
為什么上面的代碼運行沒有任何錯誤?
它產生警告: 'B.Foo()' hides inherited member 'A.Foo()'. Use the new keyword if hiding was intended.
'B.Foo()' hides inherited member 'A.Foo()'. Use the new keyword if hiding was intended.
因此,編譯器會警告您潛在的錯誤,但這是有效的,並且B.Foo
方法隱藏了A.Foo
一個。
我們是否在創建B的實例(如果是),那么當我們編寫a.Foo()時,應該調用b類的foo()函數,但是卻調用了a類的foo()函數,為什么?
您正在A
變量上調用Foo
。 所以,即使這A
實例實際上B型的是,你調用類型的變量的方法A
。
在第二個示例中, B.Foo
覆蓋 A.Foo
,這意味着該方法的邏輯已被替換 。
在第一個示例中, B.Foo
隱藏了 A.Foo
的實現。 不涉及繼承。 因此,如果類型A的變量包含類型B的實例(即A a = new B();
),則將使用A的實現。
我們可以直接創建b的實例並調用foo(),但是為什么人們寫這樣的代碼A a = new B()然后調用a.foo()呢? 編寫這種代碼可以實現什么樣的目標。 謝謝
不問自己為什么要寫A a=new B()
,而是問自己:為什么要使用new
方法?
原因之一可能是要克服無法覆蓋A.Foo
的事實,因為它沒有被標記為虛擬的。 假設您獲得了A
類,該類在無法修改的第三方程序集中實現。 如果使用您自己的類B
擴展該類,則使用new
方法隱藏其實現,並寫成B b = new B(); b.Foo();
B b = new B(); b.Foo();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.