[英]Why does this sometimes mean base?
特定
public class Animal
{
public Animal()
{
Console.WriteLine("Animal constructor called");
}
public virtual void Speak()
{
Console.WriteLine("animal speaks");
}
}
public class Dog: Animal
{
public Dog()
{
Console.WriteLine("Dog constructor called");
this.Speak();
}
public override void Speak()
{
Console.WriteLine("dog speaks");
base.Speak();
}
}
this.Speak()
調用Dog.Speak()
。 從狗中刪除Speak()
並突然this.Speak()
調用Animal.Speak()
。 為什么this
行為這種方式? 換句話說,為什么this
意味着base
或this
?
對我來說,對base.Speak()
的顯式調用更有意義。 特別是當說話不是虛擬時,令人驚訝的是當刪除virtual
時仍然會調用Speak()。 我從OO意義上理解IS-A關系,但我不能在C#中解決這個特定問題。 當人們編寫神級UI(幾乎每個企業都這樣做)時,這尤其令人討厭。 當我應該看“基地”時,我正在尋找“這個”里面的“Speak()”。
這並不是說。 它,如果有內speak方法dog
,那么它就是一個override
基方法的。 如果它不存在,則調用dogInstance.Speak將在任何Dog的基類中查找Speak()方法。
子類自動從其基類繼承行為。 如果除了繼承Dog
from Animal
之外什么都不做,那么this.Speak()
和base.Speak()
都引用了在Animal
中實現的Speak()
版本。
特殊事情開始發生的地方就是Dog
覆蓋Speak()
。 除非Speak()
是virtual
否則這是不可能的。 ( virtual
關鍵字不控制繼承,它控制覆蓋。)
只有當Dog
覆蓋Speak()
, base.Speak()
做一些特別的事情:在這種情況下,調用Speak()
(或this.Speak()
)將執行Dog
的實現,因為它override
Animal
的實現。 這是base
變得有用的地方:它允許您通過指定要執行基類的實現而不是覆蓋來繞過此行為。
這種風格的一個常見用途是構造函數。 例如:
public class Animal
{
private readonly string _name;
public Animal() : this("Animal") { }
protected Animal(string name) { _name = name; }
public void Speak() { Console.WriteLine(_name + " speaks"); }
}
public class NamedAnimal : Animal
{
public NamedAnimal(name) : base(name) { }
}
// usage:
(new Animal()).Speak(); // prints "Animal speaks"
(new NamedAnimal("Dog")).Speak(); // prints "Dog speaks"
在此示例中, NamedAnimal
無法訪問_name
字段,但仍可以通過調用基類的構造函數來間接設置它。 但是基類的簽名與基類中的簽名相同,因此必須使用base
指定。
對於非構造函數,獲取無法訪問的行為也很有用。 例如,如果Animal.Speak
是虛擬的,那么我們可以使用覆蓋來對其進行處理,而不是簡單地替換它:
public class NamedAnimal : Animal
{
public NamedAnimal(name) : base(name) { }
public override Speak()
{
Console.Write("The animal named ");
base.Speak();
}
}
// usage:
(new NamedAnimal("Dog")).Speak(); // Writes "The animal named Dog speaks"
這是面向對象的基本要點之一。 如果不提供覆蓋,則使用父方法。
此外,即使您刪除virtual
, Dog.Speak
調用Dog.Speak
,因為您不是以多態方式訪問this
。
this
意味着this
而已。
就在你的第一個例子中,你有一個Speak(..)
函數的覆蓋,所以this
調用一個。
在第二種情況下,沒有任何覆蓋,所以它“爬上”派生樹並選擇第一個合適的函數。 在你的情況下,一個是Animal
Speak(..)
。
VB.Net有MyClass
關鍵字來做到這一點(而不是在My
關鍵字,這相當於this
在C#)。 不幸的是,C#中沒有MyClass
等效關鍵字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.