2010-02-11 4 views
4

필자는 레거시 코드로 작업하면서 책을 읽었으며, 가짜 생성을 통한 단위 테스트에서 테스트하기 어려운 메서드를 재정의한다는 개념을 가지고 놀았습니다. 나는 내가 생각했던 것의 모범을 보여 주었고, 나는 기대했던 것과 다르게 행동했다. C#에서 상속과 메서드 오버로딩이 어떻게 작동하는지에 대한 이해에서 구멍을 발견했다고 생각합니다. 누군가 내가 여기에서 무슨 일이 벌어지고 있는지 이해할 수 있는지 궁금합니다.인터페이스를 구현 한 후에 메소드를 재정의하는 것이 왜 발생합니까?

public class Dog : IAnimal 
{ 

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

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

} 

을 다음과 같이 나는이 클래스를 사용하는 경우 : 다음과 같이 그때 동물 인터페이스의 구현을 만들

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

:

나는 다음과 같은 인터페이스를 가지고

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

다음 출력이 표시됩니다. 우위 Moved

이제 Dog 클래스를 단위 테스트 할 필요가 있지만 MakeSound() 메서드 중 하나를 재정의해야 할 필요가있는 것처럼 보이게 할 수 있습니다. 이유는 클래스를 테스트하기가 어렵 기 때문입니다.

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

나는 다음과 같은 출력을 얻을 : 으릉을

는 내가 개 클래스를 확장하고 다음과 같이 나는이 클래스를 사용하면 MakeSound

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

하는 방법을 만들어 가짜 개를 만들 이동 됨

내가 예상했던대로 : 바크 나는 다음 FakeDog 클래스는 동물의 인터페이스를 구현하고 그것을 사용하는 경우, 그러나

을 이전 :

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

나는 다음과 같은 출력을 얻을 : 껍질 이

난 그냥 이해 꿔을 이전 이것이 Dog 클래스를 방금 연장했을 때 예상했던대로이 메소드가 현재 대체 된 이유입니다. 아무도 나를 똑바로 설정할 수 있습니까?

답변

4

첫 번째 경우에 을 숨기는 새로운 방법을 만드는 경우 IAnimal.MakeSound의 원래 구현입니다. 이를 명백히하기 위해 new 키워드를 사용하라는 경고가 표시되어야합니다.

IAnimal으로 다시 구현됩니다. 인터페이스를 구현하려면 override 키워드가 필요하지 않습니다 (언어 디자이너 이 필요하면 좋을 수도 있음).

인터페이스를 다시 구현하지 않으려면 DogMakeSound을 가상으로 만든 다음 FakeDog으로 명시 적으로 재정의 할 수 있습니다. 그 시점에서 해결할 수있는 해결책은 단 하나 뿐이며 모든 것을 이해하는 것이 더 간단합니다. 가능한 경우 reimplementation 및 메서드 숨기기를 피하려고합니다.

+0

이유 ' LinqPad에서 실험을 수행했기 때문에 경고 메시지가 표시됩니다. 비록 설명을 주셔서 감사합니다. 추출과 오버라이드 메소드 리팩토링을 사용할 때 메소드를 제대로 재정의하려면 가상으로 메소드를 생성해야한다는 것을 기억해야합니다. – mezoid

2

(죄송합니다 질문과 대답,하지만 당신은 진정으로 유익이 실험을 찾을 수있는 경우) 다음과 같이 개를 구현할 때 어떻게됩니까 : 당신은 선언하는 데 필요한 "가상"

+0

내가 그렇게 할 때 Dog 클래스를 확장하면 override 키워드를 사용하여 메서드를 재정의 할 수 있습니다. 내 경우에는 내가 직장에서 만나는 대부분의 레거시 코드가 가상으로 표시된 메소드를 가지고 있지 않기 때문에 기존 클래스 메소드를 가상으로 만들고 싶지 않으면 어떻게 작동 하는지를보고자 노력 중입니다 – mezoid

1

public class Dog : IAnimal 
{ 

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

//... 

FakeDog 클래스의 Dog 클래스와 재정 거기에 virtualMakeSound 방법 :

관련 문제