2016-04-27 17 views
0

In den folgenden C# SchnipselWarum kann ein Compiler die Methode nicht außer Kraft setzen?

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(); 
    } 
} 

die Methode aufgerufen werden soll, wird zur Laufzeit bestimmt. Warum genau kann der Compiler nicht herausfinden, welche Methode er aufrufen soll?

Warum sieht der Compiler nicht, dass sich an auf ein Dog Objekt bezieht und dann die Methode aus dieser Klasse auswählt?

Und wie bestimmt die Laufzeit, welche Methode aufgerufen werden soll?

+0

Haben Sie jemals von Abstraktion gehört? –

+0

Mine sagt Dog Sound, wenn ich dies kompilieren es scheint mir perfekt gut – BugFinder

+0

Sie haben nicht gefragt, was die Ausgabe zur Laufzeit wäre. In der Tat haben sie in der eigentlichen Frage ziemlich deutlich gemacht, dass sie wissen, was zur Laufzeit passiert. Die Frage war, warum der Compiler nicht weiß, dass "an" zu einer Kompilierzeit ein "Hund" ist. – Nick

Antwort

0

Sie haben dem Compiler gesagt, dass die Variable vom Typ Animal ist. Es sieht nur auf Deklarationen, während Sie erwarten, dass es Ihren Code ausführt, um herauszufinden, was Sie meinen. So geht es nicht.

3

Das hört sich sehr nach einer Prüfung/Hausaufgabenfrage an. Aber lassen Sie mich Ihre Frage mit einer anderen Frage beantworten. Betrachten Sie den folgenden Code ein:

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(); 
} 

Wie wird der Compiler wissen, bei der Kompilierung welche Methode aufrufen soll? Es kann nicht, nur zur Laufzeit ist der Betontyp bekannt.

0

Betrachten Sie folgenden Code:

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(); 
    } 
} 

Wenn Compiler virtuelle Anrufe während der Kompilierung bestimmen wird nicht während der Laufzeit dann MakeSoundAbstract Methode wird immer MakeSound Methode der class Animal auszuführen, so verlieren werden wir hier die Macht der abstraction.

0

Betrachten Sie diese Änderung an Ihrem Code:

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(); 
    } 
    } 
} 

Nun ist es unmöglich zu wissen, welche Art von Tier bei der Kompilierung zu erzeugen, wie es am Tag der Woche abhängt, wenn der Code tatsächlich ausgeführt wird. Montags erhalten Sie einen Hund, aber zu jeder anderen Zeit erhalten Sie eine Katze. Dies ist ein entscheidender Vorteil von Polymorphie - Typen werden nicht vom Compiler eingebacken, sondern werden im laufenden Betrieb abgeleitet, wenn der Code ausgeführt wird. Polymorphie erlaubt Ihnen, mit diesen abgeleiteten Typen zu arbeiten, obwohl Sie nicht genau wissen, was sie sein werden, wenn Sie Ihren Code schreiben (aber Sie wissen, dass es sich um alle Arten von Tieren handelt).

Verwandte Themen