2009-05-20 48 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 ..秒快速:) ..反正使用新的不一樣的覆蓋;新的隱藏父成員,這種方式不再是多態性。 – Galilyou 2009-05-20 09:19:24

+0

@José,謝謝你做我所需要的。 – WileCau 2009-05-20 09:34:56

2

NO。你仍然可以隱藏你的的

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

PS繼承屬性:這不再是虛擬/替代關係(即無多態調用)

+0

@ 7alwagy,謝謝。在我的情況下,虛擬/覆蓋並不重要,我只是認爲我需要它來覆蓋基本屬性。使用'新'而不是'覆蓋'來做詭計。 – WileCau 2009-05-20 09:36:46

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