降低基类属性的可见性

Posted

技术标签:

【中文标题】降低基类属性的可见性【英文标题】:Decreasing the visibility of base class properties 【发布时间】:2012-03-01 18:48:33 【问题描述】:

我创建了一个基类,它具有许多公共属性并且被完美地使用。现在我想使用这个类来派生其他类,但我不希望它的某些属性暴露在继承它的派生类之外。有没有办法使基类的公共属性不能在其派生类之外公开。(要隐藏的属性是公共的,因为它们在继承它的其他类中使用)。任何帮助都将受到高度重视。

【问题讨论】:

en.wikipedia.org/wiki/Liskov_substitution_principle 【参考方案1】:

你想让他们protected。

来自 MSDN:受保护的成员可在其类内和派生类实例中访问。

【讨论】:

+1,但为了清楚起见,您可能需要补充一点,在基类中需要对其进行保护。 他可能认为这意味着他可以更改它们的可见性在派生类中。 看起来他希望公共属性仍在基类中但不在派生类中,因此这违反了原始问题的 cmets 中所示的 Liskov 原则。 @bdparrish 这就是我的想法,直到我读到倒数第二句。 “要隐藏的属性是公共的,因为它们在继承它的其他类中使用” i cnt 使它们受到保护,因为它们以前被使用过并且可以完美地工作并且可以在派生类之外公开。但现在正在派生一个新类,除了两个属性外,它需要几乎相同的属性和方法。 这种情况,请看“里氏替换原理”的评论【参考方案2】:

我同意 cadrell0 关于将它们标记为受保护的观点,但如果您正在寻找属性实际上是 public 但对某个派生类的用户隐藏的解决方案,您可以使用 explicit interface

interface IHaveMethodsYouCanHide  void Foo(); 
class Base : IHaveMethodsYouCanHide  public void Foo()  
class NonHidingDerived : Base  
class HidingDerived : Base, IHaveMethodsYouCanHide

  void IHaveMethodsYouCanHide.Foo() 

使用此代码,HidingDerived 类型的标识符将不允许调用 Foo(除非首先转换为 IHaveMethodsYouCanHide)。

【讨论】:

【参考方案3】:

您所要求的根本不可能。如果类型 B 继承自类型 A,那么它“是”类型 A。B 至少具有与类型 A 相同的可访问合同。在不从根本上违反本合同的情况下,没有办法隐藏 A 的公共成员。

如果您发现自己处于想要使用 A 但只公开属性子集的场景中,那么继承不是正确的解决方案:包含是正确的解决方案。

public class B  
  private A m_wrapped;

  // Expose only the properties you want to expose here

【讨论】:

你实际上可以在派生类型中隐藏基类型的成员,阅读我的答案与显式接口实现 @payo 不会改变现有成员的可见性。当从对 baes 的引用中可以看到派生的实例时,它们仍然可以访问。 从派生类的使用中可以看出,它确实改变了它们的可见性(您也可以通过限制标识符为基类型来引用它)。我发现做出这种区分很重要,因为最初的问题可能是询问如何隐藏,而我的回答只是显示了可以隐藏的一种解决方案。

以上是关于降低基类属性的可见性的主要内容,如果未能解决你的问题,请参考以下文章

我应该使用React State进行用户交互(切换可见性类)吗?

Three.js开发指南---使用three.js的材质(第四章)

Winform窗体基本属性

C++ 继承&多态

使用基类反映派生类的属性

记录抽象基类的属性?