Why does method overriding happen only after the interface is implemented?

I read the book Effectively Working with Legacy Code, and I played with the concept of overriding complex testing methods in unit tests by creating fakes. I put together an example of what I thought would work, and this led to behavior different from what I expected. I think I just opened a hole in my understanding of how method inheritance and overloading work in C #, and I was wondering if anyone could help me understand what is going on here.

I have the following interface:

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

Then I create an implementation of the animal interface as follows:

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

When I use this class as follows:

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

I get the following conclusion: Woof Moved

Now let's pretend that I need the unit test class Dog, but one of the methods, MakeSound (), must be overridden, because for some reason it makes testing the class difficult.

I create a fake dog by extending the Dog class and creating the MakeSound method

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

When I use this class as follows:

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

I get the following conclusion: Woof Moved

I expected it to be: Lai Moved

However, if I have a FakeDog class, implement the animal interface and use it:

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

I get the following output: Lai Moved

I just want to understand why this now cancels the method, as I expected when the Dog class was just extended. Can anyone direct me directly to this?

+4
source share
3 answers

In the first case, you create a new method that hides the original implementation of IAnimal.MakeSound . You should have seen a warning that you are using the new keyword to make this explicit.

In the second case, you IAnimal . The override keyword is not required to implement the interface (although it might have been nice if the language developers required it).

To avoid reimplementing the interface, you can make MakeSound virtual in Dog , and then explicitly override it in FakeDog . At this point, there is only one possible resolution, and everything is easier to understand. I try to avoid re-implementation and method whenever possible.

+4
source

(Sorry for the answer to the question, but you can really find this experiment informative). What happens when you implement a dog as follows:

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

Pay attention to the "virtual"

+2
source

You need to declare the MakeSound method as virtual in the Dog class and override it in the FakeDog class:

 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"); } } 
+1
source

Source: https://habr.com/ru/post/1300980/


All Articles