2009-05-20 7 views
9

나는 공통 조상이 다양한 속성을 설정하는 데 관련된 모든 논리를 담당하는 클래스 집합을 만들기 위해 노력하고 있으며 자손은 속성에 대한 액세스를 변경하는지 여부에 따라 그들은 특별한 후손에게 요구된다.속성의 액세스 한정자를 늘리는 방법

내가 컴파일러 오류 얻을 아래와 같이 나는 그것을 할 때 :

" '보호'멤버를 상속 재정의하는 경우 액세스 한정자를 변경할 수 없습니다 것은"나는에 노력하고있어 달성 할 수있는 방법이 있나요을 해야 할 것? 감사합니다

public class Parent 
{ 
    private int _propertyOne; 
    private int _propertyTwo; 

    protected virtual int PropertyOne 
    { 
      get { return _propertyOne; } 
      set { _propertyOne = value; } 
    } 

    protected virtual int PropertyTwo 
    { 
      get { return _propertyTwo; } 
      set { _propertyTwo = value; } 
    } 
} 

public class ChildOne : Parent 
{ 
    public override int PropertyOne // Compiler Error CS0507 
    { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    // PropertyTwo is not available to users of ChildOne 
} 

public class ChildTwo : Parent 
{ 
    // PropertyOne is not available to users of ChildTwo 
    public override int PropertyTwo // Compiler Error CS0507 
    { 
     get { return base.PropertyTwo; } 
     set { base.PropertyTwo = value; } 
    } 
} 

답변

11

는 다음과 같이 부모의 보호 속성을 숨기기 위해 "새로운"대신 "재정의"중 하나를 사용하여이 작업을 수행 할 수 있습니다

public class ChildOne : Parent 
{ 
    public new int PropertyOne // No Compiler Error 
    { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    // PropertyTwo is not available to users of ChildOne 
} 

public class ChildTwo : Parent 
{ 
    // PropertyOne is not available to users of ChildTwo 
    public new int PropertyTwo 
    { 
     get { return base.PropertyTwo; } 
     set { base.PropertyTwo = value; } 
    } 
} 
+2

OOPS .. 초 빠른 :) .. 어쨌든 새로운 것을 사용하는 것은 오버라이드와 동일하지 않습니다. new는 부모 멤버를 숨기고 더 이상 다형성이 아닙니다. – Galilyou

+0

@ José, 감사합니다. – WileCau

2

NO. 그럼에도 불구하고 당신이 당신의

public class ChildTwo: Praent { 
    public new int PropertyTwo { 
     // do whatever you want 
    } 
} 

PS와 함께 상속 재산을 숨길 수 있습니다 : 이것은 당신이 액세스를 변경할 수 없습니다

+0

@ 7alwagy, 감사합니다. 내 경우 가상/재정의는 중요하지 않습니다. 방금 기본 속성을 재정의해야한다고 생각했습니다. '대체'대신 '새'를 사용하면 트릭을 수행합니다. – WileCau

5

더 이상 가상/재정의 관계 (즉, 어떤 다형성 호출)입니다,하지만 당신은 다시 선언 할 수 있습니다 큰 액세스 할 수있는 구성원 :

public new int PropertyOne 
{ 
    get { return base.PropertyOne; } 
    set { base.PropertyOne = value; } 
} 

문제 이것은 다른PropertyOne, 그리고 예상대로 가상 상속 /가 작동하지 않을 수 있다는 것입니다. 위의 경우 (여기서 우리는 단지 base.*이라고 부르고 새 메소드는 가상이 아닙니다) 아마 괜찮을 것입니다. 당신이이 위의 실제 다형성 이 필요하면, 당신은 중간 클래스를 도입하지 않고 그것을 (AFAIK) 할 수 없다 (이후 당신은 할 수 없습니다 newoverride 같은 종류의 같은 멤버) :

public abstract class ChildOneAnnoying : Parent { 
    protected virtual int PropertyOneImpl { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    protected override int PropertyOne { 
     get { return PropertyOneImpl; } 
     set { PropertyOneImpl = value; } 
    } 
} 
public class ChildOne : ChildOneAnnoying { 
    public new int PropertyOne { 
     get { return PropertyOneImpl; } 
     set { PropertyOneImpl = value; } 
    } 
} 

위의 중요한 점은 무시할 단일 가상 멤버 인 PropertyOneImpl이 여전히 있다는 것입니다.

+0

@Marc, 내가 가상/오버라이드가 필요하다고 생각했기 때문에 아마도 혼란 스러웠다.하지만이 경우 분명히 그렇지 않다. 다형성으로 할 필요가있을 때를위한 답에 대한 링크를 유지할 것입니다. 설명과 샘플 코드를 제공해 주셔서 감사합니다. – WileCau

관련 문제