Por que substituir um método só ocorrem depois que implementar uma interface?
-
19-09-2019 - |
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?
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");
}
}