2016-04-27 118 views
0

在下面的C#代碼段爲什麼編譯器不能解析方法覆蓋?

public class Animal 
{ 
    public virtual void MakeSound() 
    { 
     Console.WriteLine("Animal sound"); 
    } 
} 

public class Dog:Animal 
{ 
    public override void MakeSound() 
    { 
     Console.WriteLine("Dog sound"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Animal an = new Dog(); 
     an.MakeSound();   
     Console.ReadLine(); 
    } 
} 

被稱爲在運行時確定的方法。爲什麼編譯器無法弄清楚,調用哪個方法?

爲什麼編譯器看不到an引用了Dog對象,然後從該類中選擇方法?

運行時如何確定要調用哪個方法?

+0

你有沒有聽說過抽象? –

+0

我說狗的聲音,如果我編譯它,這對我來說似乎是完全不錯的 – BugFinder

+0

他們沒有問在運行時的輸出是什麼。事實上,他們在實際問題中明確表示他們知道運行時正在發生的事情。問題是爲什麼編譯器不知道'an'是編譯時的'Dog'。 – Nick

回答

0

你告訴編譯器該變量是Animal類型的。它只看到聲明,而你期望它執行你的代碼來找出你的意思。這不是它的工作原理。

3

這聽起來像一個考試/家庭作業問題非常多。但讓我用另一個問題回答你的問題。 考慮下面的代碼:

static void Main(string[] args) 
{ 
    var random = new Random(); 
    Animal an = null; 
    if (random.NextDouble() < 0.5) { 
     an = new Dog(); 
    } else { 
     an = new Cat(); 
    } 

    an.MakeSound();   
    Console.ReadLine(); 
} 

如何編譯器應該在編譯時知道哪種方法來調用?它不能,只有在運行時纔會知道具體的類型。

0

考慮下面的代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Animal dog = new Dog(); 
     MakeSoundAbstract(dog); 

     Animal an = new Animal(); 
     MakeSoundAbstract(an); 

     Console.ReadLine(); 
    } 

    static void MakeSoundAbstract(Animal animal) 
    { 
     animal.MakeSound(); 
    } 
} 

如果編譯器會在運行時編譯期間確定的虛擬呼叫不那麼MakeSoundAbstract方法將總是執行class Animal所以我們正在失去這裏的abstraction功率MakeSound方法。

0

考慮這改變了代碼:

public class Animal 
{ 
    public virtual void MakeSound() 
    { 
    Console.WriteLine("Animal sound"); 
    } 
} 

public class Dog : Animal 
{ 
    public override void MakeSound() 
    { 
    Console.WriteLine("Woof!"); 
    } 
} 

public class Cat : Animal 
{ 
    public override void MakeSound() 
    { 
    Console.WriteLine("Purrrrrrrrrrrrrr"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    Animal an = GetAnimal(DateTime.Now); 
    an.MakeSound();   
    Console.ReadLine(); 
    } 

    private Animal GetAnimal(DateTime dateTime) 
    { 
    if (dateTime.DayOfWeek == DayOfWeek.Monday) 
    { 
     return new Dog(); 
    } 
    else 
    { 
     return new Cat(); 
    } 
    } 
} 

現在是不可能知道要創建什麼類型的動物在編譯時間,因爲它取決於星期的代碼時實際運行。星期一你會得到一隻狗,但在任何時候你會得到一隻貓。這是多態性的一個明顯的好處 - 類型不是由編譯器烘焙的,而是在代碼執行時即時導出的。多態性允許您使用這些派生類型,即使您在編寫代碼時(但您確實知道它們都是所有類型的動物)並不確切知道它們會是什麼。

相關問題