2017-11-25 18 views
0

최근 클래스 생성/모델링과 관련된 문제가 발생했습니다.인터페이스를 추상 클래스와 비교하여 결정할 때 올바른 구현은 무엇입니까?

클래스로 동물 동물 왕국. 클래스를 사용하여 가상 동물원으로 표현 된 다양한 객체를 만듭니다. 이 가상 동물원에 20 마리의 동물을 넣으십시오 (프로그램의 기본 방법으로 각 동물이 소리를 내도록하십시오.이 동물은 20 종이 아니어야합니다).

나는이 문제에 대해 생각하고 인터페이스가 아닌 추상적 인 클래스 Animal로 가기로 결정했습니다. 그런 다음 두 마리의 Bird, Mammal을 Animal에서 상속받은 클래스로 추가했습니다.

내 구현

public abstract class Animal{ 

     abstract Sound MakeSound(); 
    } 

    public class Bird : Animal 
    { 
     private Sound _sound; 
     public Bird(Sound sound){ 
     _sound = sound; 
    } 
    public Sound MakeSound(){ 
      return _sound; 
     } 
    } 
//same as above with Mammals 

public class Program 
{ 
    Animal crow = new Bird("Crow sound"); 
    Console.WriteLine(crow.MakeSound()); 

Animal dog = new Mammal("Dog sound"); 
    Console.WriteLine(dog.MakeSound()); 

// and so on with other animals 
} 

내 질문입니다 - 내 구현 뭐가 문제

  1. ?
  2. oops 개념에 따라 동물 왕국을 설계하는 올바른 방법은 무엇입니까?
  3. 어떤 시나리오에서 우리는 추상 클래스를 통해 인터페이스를 사용하고 그 반대도 마찬가지입니다. (실제 예와 함께)

그런 문제를 개선 할 수있는 온라인 자료에 유익한 제안을하십시오. 감사합니다. .

+0

안녕하세요. 코드 검토라는 Stack Overflow의 자매 사이트에서 더 나은 응답과 도움을 얻을 것이라고 생각합니다. https://codereview.stackexchange.com – raykrow

+0

생성자를 통해 사운드를 제공하면 클래스의 전체 계층 구조를 만드는 것이 바람직하지 않습니다. 당신은 하나의 클래스'Animal'을 가질 수 있고 그것으로부터 모든 동물을 생성 할 수 있습니다 :'var dog = new Animal ("Dog sound");'. 예제를 이해하기 위해서는 이러한 클래스의 특정 종에 고유 한 코드가 있어야합니다. –

답변

9

우선, "클래스 계층 구조에서 동물 왕국을 모델로 만들어라"는 일반적인 초보자 연습이며, 예를 들어 자주 동물, 포유류, 기린, 호랑이 등을 사용한다는 사실을 깨닫는 것이 중요합니다. 예를 들어 항상 - OO 기술을 사용하여 해결하는 것은 현실적인 문제가 아닙니다. 단순히 이미 잘 이해하고있는 도메인에 대해 생각함으로써 객체 지향 프로그래밍의 개념에 대해 생각하게하려는 것입니다.

동물 목록을 관리하는 소프트웨어가있는 실제 동물원은 조류와 공통점이있는 것과 포유류가 공통으로 갖고있는 것을 포함하지 않기 때문에 클래스 계층 구조를 만들지 않습니다. 동물 왕국 유추가 OO를 사용하는 데 유용하지만 실제로 실제 계층 구조에있는 모든 기능을 클래스 계층에서 모델화해야한다는 신념을 버리지 않는 것이 중요합니다.

그렇기 때문에 나머지 비판은 실제로 동물 왕국을 운동으로 모델링한다고 가정한다고 가정합니다.

둘째, 구현의 근본적인 문제는 계층 구조가 충분히 깊지도 않거나 너무 깊지도 않다는 점입니다.문제는 포유 동물과 새는 추상적 인 것입니다포유류 인 것만으로 또는 새가입니다. 당신이 원하는 것은 동물을 확장하는 추상 클래스의 새입니다. 그리고 나서 Bird를 확장하는 콘크리트 (아마도 봉인 된) 클래스 Crow입니다.

그러면 질문해야 할 질문은 : 포유류와 조류의 수준이 정말로 필요합니까? They are 내 프로그램에 유용합니까? 나는 포유류를 먹을 수 있지만 도마뱀을 먹을 수있는 방법을 가지지 않을 것인가? 유용하지 않다면 그것을 제거하고 동물에서 까마귀로 바로 가십시오.

세 번째로, 까마귀가 만드는 소리는 "까마귀 소리"가 아니라 "거북이"입니다. :-)

넷째, 당신의 최선의 질문에 대답 : 당신이 여러 관련이없는 일을 할 때 일반적으로하지만, 다른 구현과 같은 일을 "할 수있다"고 인터페이스를 사용하고 구현을 공유하는 추상 클래스 를 사용 "종류의"관계가있는 클래스들 사이의 세부 정보.

소리를내는 것은 서로 관련이없는 많은 일을 할 수있는 것입니다. 새와 피아노는 같은 종류가 아니며 서로 다른 메커니즘을 가지고 있지만 둘 다 소리를 낸다. 그래서 사운드를 만드는 것은 인터페이스로 표현되어야합니다. 새는 일종의 동물이며 새가 특화된 모든 동물에게 공통적 인 기능이있을 수 있습니다.

간단히 말해서, 새는 일종의 동물이므로 서브 클래스 여야합니다. 새는 소리를 낼 수 있고 다른 많은 것들도 할 수 있으므로 소리를내는 것이 인터페이스가되어야합니다.

+0

Lippert님께 감사드립니다. 당신의 대답은이 주제에 대한 내 마음에서 안개를 제거했습니다. 매우 감사. – allaboutbits

0

인터페이스를 사용하려는 이유 중 하나는 C#이 다중 상속을 지원하지 않는다는 것입니다.

일반적으로 모델이 아닌 능력이나 기능으로 인터페이스를 생각하고 싶습니다.

뭔가 같은 : 이제

public interface ISwimable 
    { 
     int SwimmingSpeed { get; set; } 
    } 

    public interface IWalkable 
    { 
     int RunningSpeed { get; set; } 
    } 

내가 물에 사는 동물이 있다면 나는 그것이 ISwimable을 구현하고 싶습니다, 내가 걸을 수있는 동물이있는 경우, 그 클래스는 경우 IWalkable를 구현해야하고 그것은 둘 다 할 수 있고, 둘 다 구현할 수 있습니다.