簡體   English   中英

為什么這有時意味着基數?

[英]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意味着basethis

對我來說,對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"

這是面向對象的基本要點之一。 如果不提供覆蓋,則使用父方法。

此外,即使您刪除virtualDog.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM