Pourquoi ne remplaçant une méthode se produit seulement après que j'implémentent une interface?

StackOverflow https://stackoverflow.com/questions/2243830

Question

J'ai lu dans le livre Travailler efficacement avec Legacy Code et j'ai joué avec le concept de passer outre difficile de méthodes d'essai dans les tests unitaires par la création d'un faux. Je mets ensemble un exemple de ce que je pensais travailler et il a fini par se comporter différemment que je ne m'y attendais. Je pense que je viens de découvrir un trou dans ma compréhension de la façon dont fonctionne la surcharge héritage et méthode en C # et je me demandais si quelqu'un pouvait me aider à comprendre ce qui se passe ici.

J'ai l'interface suivante:

public interface IAnimal
{
    void MakeSound();
    void Move();
}

Je crée alors une implémentation de l'interface animal comme suit:

public class Dog : IAnimal
{

public void MakeSound()
{
    Console.WriteLine("Woof");
}

public void Move()
{
    Console.WriteLine("Moved");
}

}

Quand j'utilise cette classe comme suit:

IAnimal myanimal = new Dog();
myanimal.MakeSound();
myanimal.Move();

Je reçois la sortie suivante: Trame Déplacé

Maintenant, fais semblant que je LETs ai besoin de test unitaire de la classe Dog, mais l'une des méthodes, MakeSound (), doit être ignoré car il rend la classe difficile à tester pour une raison quelconque.

Je crée un chien faux en étendant la classe de chien et de créer une méthode pour MakeSound

public class FakeDog : Dog
{
    public void MakeSound()
    {
         Console.WriteLine("Bark");
    }
}

Quand j'utilise cette classe comme suit:

IAnimal myanimal = new FakeDog();
myanimal.MakeSound();
myanimal.Move();

Je reçois la sortie suivante: Trame Déplacé

Je me attendais à été: Écorce Déplacé

Cependant, si je puis la classe FakeDog implémenter l'interface animal et de l'utiliser:

public class FakeDog : Dog, IAnimal
{
    public void MakeSound()
    {
         Console.WriteLine("Bark");
    }
}

Je reçois la sortie suivante: Écorce Déplacé

Je suis juste vouloir comprendre la raison pour laquelle cela l'emporte maintenant la méthode que je m'y attendais quand je venais d'être étendu la classe Dog. Quelqu'un peut-il me détromper à ce sujet?

Était-ce utile?

La solution

Dans le premier cas, vous créez une nouvelle méthode cache la mise en œuvre originale de IAnimal.MakeSound. Vous auriez dû voir un avertissement vous indiquant que vous utilisez le mot-clé new pour en faire explicitement.

Dans le second cas, vous êtes réimplémenter IAnimal. La mise en œuvre d'une interface ne nécessite pas le mot-clé override (bien qu'il aurait été bien si les concepteurs de langue HAD que nécessaire).

Pour éviter une nouvelle implémentation de l'interface, vous pouvez faire MakeSound virtuelle dans Dog, puis explicitement dans remplacer FakeDog. À ce moment-là, il n'y a qu'une seule résolution possible en jeu, et tout est plus simple à comprendre. J'essaie d'éviter reimplementation et cacher la méthode autant que possible.

Autres conseils

(Désolé pour répondre à une question, mais vous pourriez vraiment trouver cette expérience informative) Qu'advient-il lorsque vous implémentez chien comme suit:

public class Dog : IAnimal
{

public virtual void MakeSound()
{
    Console.WriteLine("Woof");
}

//...

Notez le "virtuel"

Vous devez déclarer la méthode MakeSound comme virtual dans la classe Dog et override dans la classe FakeDog:

public class Dog : IAnimal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Woof");
    }

    public virtual void Move()
    {
        Console.WriteLine("Moved");
    }
}

public class FakeDog : Dog
{
    public override void MakeSound()
    {
        Console.WriteLine("Bark");
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top