代码之家  ›  专栏  ›  技术社区  ›  David Božjak

限制对继承属性C的访问#

  •  1
  • David Božjak  · 技术社区  · 15 年前

    假设我继承了一个具有多个公共属性和/或方法的类,但是我不希望它们是我的类的公共属性/方法——换句话说,我希望使这些属性保护我的类的属性。

    这能实现吗?

    我希望我是足够清楚的,如果不请让我知道,会尽量解释自己更好。

    编辑:

    好吧,谢谢你们的回答,不过我觉得我不够清楚。我要做的是:

    我编写了一个扩展ListView控件的Windows控件。ListView具有可修改的公共集合项。这很好,但是由于需要额外的数据,我编写了向ListView添加项的新方法。

    到目前为止,一切都很好,但是items集合仍然可以被任何东西修改,这是一个问题,因为如果通过直接操作items集合添加了一个项,则不会收集我需要的所有数据,从而导致错误。

    由于我们希望在不同的项目中多次重用此控件,因此我们担心迟早会使用向项集合添加项的默认方法(实际上只是时间问题)。我们只是在寻找一种防止这种情况发生的方法,比如当items集合变得更大时抛出异常,但它的方式是预期的。

    我希望这一切现在都有意义。

    5 回复  |  直到 15 年前
        1
  •  4
  •   Robert Venables    15 年前

    永不言败。这可能不是最好的主意,但似乎对我有用。这通过在子类中重新实现它,然后使用属性隐藏它来隐藏项。我添加了一个“CustomExposedItems”属性,这样您就可以看到现有项仍然可以在基础ListView中访问。

    public partial class CustomListView : ListView
    {
        public CustomListView()
        {
            InitializeComponent();
        }
    
        public System.Windows.Forms.ListView.ListViewItemCollection CustomExposedItems
        {
            get
            {
                return base.Items;
            }
    
        }
    
        [EditorBrowsable(EditorBrowsableState.Never)]    
        [Browsable(false)]    
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Obsolete("Use the new custom way of adding items xyz")]
        public new System.Windows.Forms.ListView.ListViewItemCollection Items    
        { 
            get { throw new NotSupportedException(); }    
        }
    
    }
    
        2
  •  4
  •   Jon Skeet    15 年前

    继承就是说“您可以像使用基类那样使用这个派生类,并且它提供了专门的行为”。

    如果你 不能 以与基类相同的方式使用派生类,那么您不应该使用继承:您正在破坏 Liskov's Substitutability Principle . 在这种情况下,使用组合而不是继承。(就个人而言,我不太喜欢使用类到类的继承,而是更喜欢组合——我发现在相对较少的情况下,专门化方面确实可以毫无问题地工作。当它 干得好,不过很好!)

        3
  •  3
  •   Daniel Brückner    15 年前

    不,你不能那样做。你能做的最好的事情就是创建一个类,并包装一个由它派生的基类——但这当然会破坏继承。(我假设您不能修改基类。如果可以,您应该重新考虑设计,因为看起来新类不应该从基类派生。)

    class BaseClass
    {
         public String IWantThis { get; set; }
         public String IDoNotWantThis { get; set; }
    }
    
    class MyClass
    {
        private BaseClass baseClass = new BaseClass();
    
        public String IWantThis
        {
            get { return this.baseClass.IWantThis; }
            set { this.baseClass.IWantThis = value; }
        }
    }
    
        4
  •  1
  •   Stefan Steinegger    15 年前

    你不能通过继承来做到这一点。这实际上就是继承的意义所在。安 IS-A关系 无法减少接口。派生类必须是基类的完整表示形式。

    把你的继承变成一个参照物。您可以通过调用“基类”来重用它的实现。(组合而不是继承。)如果需要多态性,请添加公共接口或将公共部分移动到单独的抽象基类中。

        5
  •  0
  •   James Black    15 年前

    我不使用AOP,也许是PostSharp,来放置您不想使用的属性,然后您可以用您的方面以适当的方式处理它。