Pergunta

Estive lendo o livro trabalhar efetivamente com Legacy Code e eu fui brincar com o conceito de substituir difícil de métodos de teste em testes de unidade através da criação de uma farsa. Eu coloquei um exemplo do que eu pensei que iria trabalhar e acabou comportando de maneira diferente do que eu estava esperando. Eu acho que eu acabei de descobrir um buraco no meu entendimento de como herança e método de sobrecarga obras em C # e eu queria saber se alguém poderia me ajudar a entender o que está acontecendo aqui.

Eu tenho a seguinte interface:

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

Eu, então, criar uma implementação da interface animal como segue:

public class Dog : IAnimal
{

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

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

}

Quando eu usar essa classe da seguinte forma:

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

Eu recebo o seguinte resultado: trama Movido

Agora, vamos fingir que eu estou precisando de teste de unidade da classe Dog, mas um dos métodos, MakeSound (), precisa ser substituído porque ele está fazendo a classe difícil teste por algum motivo.

eu crio um cão falso estendendo a classe Dog e criando um método para MakeSound

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

Quando eu usar essa classe da seguinte forma:

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

Eu recebo o seguinte resultado: trama Movido

Eu estava esperando que possa ter sido: Latido Movido

No entanto, se eu, então, a classe FakeDog implementar a interface de animais e usá-lo:

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

Eu recebo o seguinte resultado: Latido Movido

Eu só estou querendo entender a razão pela qual isso agora substitui o método como eu esperava quando eu tinha acabado de ser estendido a classe Dog. Alguém pode me esclareceu sobre isso?

Foi útil?

Solução

No primeiro caso, você está criando um novo método que couros a implementação original da IAnimal.MakeSound. Você deve ter visto um aviso sugerindo que você usa a palavra-chave new para fazer isso explícito.

No segundo caso, você está re-implementação IAnimal. Implementação de uma interface não requer a palavra-chave override (embora possa ter sido bom se os projetistas da linguagem estiveste necessário que).

Para evitar re-implementação da interface, você poderia fazer MakeSound virtual na Dog, e, em seguida, substituí-lo explicitamente no FakeDog. Nesse ponto, só há uma solução possível envolvidos, e tudo é mais simples de entender. Eu tento evitar reimplementação e método de esconder sempre que possível.

Outras dicas

(Desculpe por responder com uma pergunta, mas você pode realmente encontrar este informativo experimento) O que acontece quando você implementa cão da seguinte forma:

public class Dog : IAnimal
{

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

//...

Observe o "virtual"

Você precisa declarar o método MakeSound como virtual na classe Dog e substituir na 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");
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top