2012-08-01 7 views
4

일반적인 파생 클래스에서 기본 클래스 메서드 숨기기 "fooString"이라면 그는 fooString.Do(5)fooString.Do("test")을 모두 호출 할 수 있지만 "fooInt"라는 Foo<int> 오브젝트를 작성하면 파생 클래스의 Do 메소드 만 호출 할 수 있습니다. 나는 T이 무엇이든 관계없이 두 번째를 선호합니다.나는 기본이 같은 클래스가

이 두 클래스의 Do 메서드는 기본적으로 동일한 작업을 수행합니다. 파생 클래스에있는 매개 변수는 주어진 매개 변수를 사용하여 Dictionary<T, int>에서 정수를 가져오고이를 사용하여 기본 클래스의 Do 메서드를 호출합니다.

그래서 나는 FooBase의 Do 메서드를 Foo<T>에 숨기려고합니다. 어떻게하면 좋을까요? 이것을 극복하는 디자인 어드바이스도 좋을 것입니다.

+0

기본 클래스의 Do를 보호하도록 고려 했습니까? – Hammerstein

+0

@Hammerstein - 네,하지만 공개해야합니다. 기본 클래스는 추상 클래스가 아니며 Do 메서드는 주요 함수이므로 public이어야합니다. –

+0

그들이 같은 일을한다면, 기본 방법을 숨겨서 얻는 것은 무엇입니까? 다른 변종이 호출되면 차이가 없어야합니다. 동일한 변이를 수행하기 때문입니다. – CodesInChaos

답변

6

(물론 클래스 이름을 변경) 그러나 그가 "fooInt"라고 불리는 Foo<int> 객체를 생성하면 그는 파생 클래스의 Do 메소드 만 호출 할 수 있습니다.

아니요, 사실이 아닙니다. 변수의 선언 된 유형이 FooBase이면 여전히 FooBase 메소드를 호출합니다. 실제로는 FooBase.Do에 대한 액세스를 차단하지 않고 있습니다. 숨어있는 것뿐입니다.

FooBase foo = new Foo<int>(); 
foo.Do(5); // This will still call FooBase.Do 

전체 샘플 코드는를 표시합니다 :

using System; 

class FooBase 
{ 
    public bool Do(int p) { return false; } 
} 

class Foo<T> : FooBase 
{ 
    public bool Do(T p) { return true; } 
} 

class Test 
{ 
    static void Main() 
    { 
     FooBase foo1 = new Foo<int>(); 
     Console.WriteLine(foo1.Do(10)); // False 

     Foo<int> foo2 = new Foo<int>(); 
     Console.WriteLine(foo2.Do(10)); // True 
    } 
} 

있다고 나는 푸에서 FooBase의 마 방법을 숨길 이유.

Liskov's Substitutability Principle에 대해 생각해 봐야합니다.

어느Foo<T> (예를 들어 그것을 보호 할) 또는FooBase.Do가 보이지 않아야 FooBase에서 (상속 대신 사용 조성물)를 도출 안된다.

+1

사실입니다. 파생 된 Do 메서드를 호출합니다. –

+0

@ d4wn : 아니요, 기본 클래스의 Do 메서드를 호출합니다. 지금 당장은 그것을 확인 하겠지만, 정말로 확신합니다 ... –

+0

@ d4wn : 변수가'FooBase' 일 때 기본 클래스의 Do 메소드를 호출한다는 것을 증명하는 짧지 만 완전한 프로그램을 보여주기 위해 제 대답을 편집했습니다. –

0

당신은 Foo<T>에서 상속하는 protected Do 방법으로 추상적 인 기본 클래스를 구축하고, 현재 FooBase 클래스를 다시 작성할 수 :

public abstract class FooBaseAbstract 
{ 
    protected bool Do(int p) 
    { 
     return true; 
    } 
} 

// You can use this one just as your current FooBase class 
public class FooBase : Foo<int> 
{ 
} 

public class Foo<T> : FooBaseAbstract 
{ 
    public bool Do(T p) 
    { 
     if (true /* some test here */) 
     { 
      return base.Do(4); 
     } 

     return false; 
    } 
} 

관련 문제