Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#是否有私有和受保护继承的概念?_C#_Inheritance - Fatal编程技术网

C#是否有私有和受保护继承的概念?

C#是否有私有和受保护继承的概念?,c#,inheritance,C#,Inheritance,C#是否有私有/受保护继承的概念,如果没有,为什么 C++ class Foo : private Bar { public: ... }; C# 我在.aspx页面中实现了一个“类似servlet”的概念,我不希望具体的类能够看到System.Web.UI.page基础的内部结构。不,仅限公共继承。您可能想要一个与NServlet实现相连接的ServletContainer类。在我的书中,不允许私有/受保护的继承并不是什么大不了的事,也可以让语言不那么混乱——比如LINQ等。我

C#是否有私有/受保护继承的概念,如果没有,为什么

C++


class Foo : private Bar {
 public:
   ...
 }; 
C#


我在.aspx页面中实现了一个“类似servlet”的概念,我不希望具体的类能够看到System.Web.UI.page基础的内部结构。

不,仅限公共继承。

您可能想要一个与NServlet实现相连接的ServletContainer类。在我的书中,不允许私有/受保护的继承并不是什么大不了的事,也可以让语言不那么混乱——比如LINQ等。我们都准备好了足够的东西来记住。

不,没有。允许这种类型的限制有什么好处?

您可以通过将类中的同一成员声明为private并使用new关键字来隐藏继承的API,使其不公开可见。请参阅MSDN。

如果您希望NServlet类不知道有关页面的任何信息,则应该研究如何使用适配器模式。编写一个将承载NServlet类实例的页面。根据您的具体操作,您可以编写一系列只知道基类NServlet的类,而不必使用asp.net页面成员污染API。

C#只允许公共继承。C++允许所有三种类型。公共继承隐含着一种“是一种”的关系,而私人继承隐含着一种“是以一种”的关系来实现的。由于分层(或合成)以一种可以更为简单的方式完成了这一点,因此私有继承仅在受保护成员或虚拟函数所需的条件下使用,根据Scott Meyers的有效C++,项目42。p> 我的猜测是,《C#》的作者并不认为有必要用这种额外的方法来实现一个类与另一个类的关系。

@bdukes: 请记住,您并不是真正地隐藏成员。例如:

class Base
{
   public void F() {}
}
class Derived : Base
{
   new private void F() {}
}

Base o = new Derived();
o.F();  // works
<>但这与C++中的私有继承相同,这也是提问者想要的。< /P>
不,没有。允许这种限制有什么好处

私有和受保护的继承有利于封装(信息隐藏)。保护*继承在C++中被支持,虽然它不是在java中。下面是我的项目中的一个例子,它将非常有用

as第三方框架**中有一个基类。它有几十种设置、属性和操作方法。基类在分配单个设置时不会进行大量检查,但如果遇到不可接受的组合,它将在稍后生成异常

我正在创建一个子类,其中包含分配这些设置的方法(例如,从文件中分配精心编制的设置)。如果不让代码的其余部分(在我的子类之外)操作单独的设置并把它们搞乱,那就太好了

,我认为C++中(它再次支持私有和受保护继承),可以将子类转换为父类并访问父的公共成员。(另请参见)不过,受保护的继承改进了信息隐藏。如果类别B1的成员需要真正隐藏在其他类别C1和C2中,则可以通过在C1和C2中生成类别B1的受保护变量来安排。B1的受保护实例将提供给C1和C2的孩子。当然,这种方法本身并不提供C1和C2之间的多态性。但是可以通过从公共接口I1继承C1和C2来添加多态性(如果需要)

***为简洁起见,将使用“受保护”而不是“私有和受保护”

**国家仪器测量工作室在我的情况下

  • 尼克

    • 我知道这是一个老问题,但我在编写C#时多次遇到这个问题,我想知道……为什么不使用接口呢

      当您创建第三方框架类的子类时,还要让它实现一个公共接口。然后定义该接口,使其仅包含希望客户端访问的方法。然后,当客户机请求该类的实例时,为其提供该接口的实例

      这似乎是C#接受的做这类事情的方式

      我第一次这样做是因为我意识到C#标准库没有字典的只读变体。我想提供对字典的访问,但不想让客户端能够更改字典中的项。因此,我定义了一个“类DictionaryEx:Dictionary,IReadOnlyDictionary,其中V:IV”其中K是键类型,V是实值类型,IV是防止更改的V类型的接口。DictionaryEx的实现非常简单;唯一困难的部分是创建一个ReadOnlyEnumerator类,但即使这样也不需要很长时间


      这种方法的唯一缺点是,如果客户机试图动态地将公共接口转换为相关的子类。要停止此操作,请将类设置为内部。如果您的客户机将您的公共接口强制转换为原始基类,我认为他们会非常清楚,他们是在自食其力。:-)

      第一个解决方案:

      受保护的内部在同一程序集中作为公共,并在其他程序集中受保护

      您需要更改不通过继承公开的类的每个成员的访问修饰符

      尽管有点限制,但此解决方案要求并强制将类继承给另一个程序集使用。因此,未知的父项将选择是否仅由继承使用。。。通常情况下,孩子们更了解建筑

      不是一个完美的解决方案,但米格
      class Base
      {
         public void F() {}
      }
      class Derived : Base
      {
         new private void F() {}
      }
      
      Base o = new Derived();
      o.F();  // works