2009-07-31 5 views
1

정말 "다형성"질문이지만 어쨌든 ... 그래서 나는 그것으로부터 상속받은 추상 클래스와 2 개의 다른 클래스를가집니다.C# 기본 다형성 질문

기본 클래스의 일부 코드에는 기본 클래스를 확장하는 클래스간에 다른 변수가 있습니다.

어떻게해야할까요? "get"메소드를 재정의 하시겠습니까? 아키텍처를 변경하여 기본 클래스에서 값을 전달하는 확장 클래스로 함수를 호출하십시오.

다음은 예제입니다 (컴파일하지 않고 약간의 예제 만 사용합니다).

public abstract class BaseAbstract class { 

    ... some code .... 

    // Here "listName" would change depending on the extending class 
    protected List<Items> getAllItems(String listName) { 

    Web.getList(listName); 

    ... some code ... 

    } 

    protected abstract List<Items> getAllItems(); 

} 

public class NewClass : BaseAbstract { 
protected override void getAllItems() { 
    return getAllItems("ListNameOfNewClass"); 
} 
} 

이것이 내가 해낸 방법이지만, IMO를 유지 관리하는 것이 명확하고 쉽지 않습니다.

모든 아이디어 나 의견 환영합니다!

+0

덧붙여서, 기본 클래스는 구현할 다른 방법을 가지고 있습니다 ... –

답변

7

아마 이런 식으로 뭔가를 선택하는 것 public로 노출 된 메서드/속성과 별도로 보호 된 기능 (getAllItems) NewClass로부터 상속받은 모든 클래스에서 사용할 수 있습니다.

나는 인터페이스를 변경했으며 순수하게 돼지 머리를 쓰지 않는 속성으로 공개했습니다. 이는 경우

public abstract class BaseClass { 

     protected abstract IList<Item> getAllItems(); 
    } 

    public class SubClass : BaseClass 
    { 
     IItemsProvider itemsProvider; 

     protected override IList<Item> getAllItems() 
     { 
      return itemsProvider.getAllItems("filter"); 
     } 
    } 

    public interface IItemsProvider 
    { 
     IList<Item> getAllItems(string name); 
    } 
+0

나는 그것이 유지하기 쉽고 간단하기 때문에 이것이 최선의 방법이라고 생각합니다. 명시된 바와 같이, 그것이 당신이 "전문화"할 필요가있는 유일한 것이라면 그것을하는 가장 좋은 방법은 아니지만 제 경우에는 완벽하다고 생각합니다. 고맙습니다! –

0

답이 맞는지 확실하지 않지만 초기화하는 동안 상속 된 클래스에서 설정 한 기본 클래스 보호 된 변수를 사용할 수 있습니까?

예 :

public abstract class Base 
{ 
    protected abstract string ListName { get; } 
    public List<Item> GetItems() 
    { 
     return Web.GetList(ListName); 
    } 
} 

public class Child : Base 
{ 
    protected override string ListName 
    { 
     get { return "MyListName"; } 
    } 
} 
+0

이 문제는 자식이 listName을 설정하도록 강요하지 않는다는 것입니다. 원래 기본 클래스를 작성하지 않았다면 어떻게 설정했는지 어떻게 알 수 있습니까? – ctacke

+0

get로 추상 속성을 보호; 한정된.그것은 개발자가 그것을 구현하도록 강요합니다 – Sekhat

2

아마 다음과 같은 접근 방식 갈 것이라고는 :

public abstract class Base 
{ 
    protected List<Items> getAllItems(String listName) 
    { 
     // Implementation 
    } 

    public abstract List<Items> Items 
    { 
     get; 
    } 
} 

public class NewClass : Base 
{ 
    public override List<Items> Items 
    { 
     get 
     { 
      return base.getAllItems("ListNameOfNewClass"); 
     } 
    } 
} 

이 내부를 유지

class test 
{ 
    protected string listName; 

    protected void getAllItems() 
    { 
     return getAllItems(listName); 
    } 
} 

class test2 : test 
{ 
    public test2() 
    { 
     base.listName = "MyUniqueList"; 
    } 
} 
+0

나는 Property를 직접 사용하는 데 동의합니다. 그러나이 구현에서 가지고있는 문제점은 프로젝트의 뒤편에있는 개발자에게 혼란을 준다는 것입니다. 그들은 Items 속성을 기반으로 다시 호출해야한다는 것을 알아야합니다. – ctacke

+0

기본 클래스의 역할이 잘 정의되고 문서화되어있는 한 엄청난 문제는 발생하지 않을 것이라고 생각하지만 다른 답변을 살펴볼 기회가 있었기 때문에 아마도 이러한 이유 때문에 작곡을 할 것입니다. – Justin

0

을 몰랐어요 당신의 서브 클래스들 사이의 변이의 차원 만이 더 이상 상속을 필요로하지 않습니다; 필요에 따라 올바른 ItemListGetter를 설정하십시오.

+0

내가 옳은지 나는 모른다. 그러나 나는이 해결책이 너무 복잡하다는 것을 안다. 그렇지 않습니까? –

4

Prefer Composition Over Inheritance.

public class Base { 
    private ItemListGetter itemListGetter; // assignment/initialization is up to you 

    private List<Items> getAllItems() { // this can now be inlined 
    return itemListGetter.getList(); 
    } 

} 

: 그리고 파티는 경우에 당신은 내가 그것을 제 3 성분을 구현하는 더 나을 생각 ... 그것은 할 수

+0

나는 그것을 명심 할 것이다! 귀하의 의견을 보내 주셔서 감사합니다! :) –

0

정말 상속을 원하면 ctacke's 해결책을 선택하십시오.

일반적으로 문제는 상속으로 해결되지 않는 것 같습니다. 상속은 특수화 된 동작을 제공하는 데 사용해야합니다. 귀하의 경우에는 구성 문제가 될 것 같습니다. 즉, 서브 클래 싱 할 필요없이 외부에서 구성하는 속성 (즉, list-name)을 제공해야합니다.

+0

글쎄, 내 예제에는 너무 특별한 방법이 없다. –