封装VS继承 - 如何使用受保护的功能?

时间:2008-11-14 11:33:12

标签: c# vb.net oop inheritance encapsulation

在C#或VB.NET等OOP语言中,如果我在超类protected中创建属性或方法,我无法在我的表单中访问它们 - 它们只能在我继承自的类中访问超级班。

要访问我需要创建它们public的那些属性或方法,这会破坏封装,或者将它们重写到我的类中,这会破坏继承。

这样做的正确方法是什么?

4 个答案:

答案 0 :(得分:2)

如果您的代码需要让某个类执行特定的操作,但是该类没有为您的代码提供执行此操作的方法,则该类不符合您的代码要求。

有点像说我有一辆带有受保护方向盘的汽车(汽车)所以我无法访问它。这辆车对我没用。

要么将这些成员公开(或者至少是内部成员)并使用它们,要么弃用该类,并使用为您的消费代码提供所需功能的类。

也许你真正想要的是一个界面。界面包含您的代码所需的成员,并在您的类上实现该接口。这里的优点是您的类可以确定通过此接口而不是继承子类来访问成员。

答案 1 :(得分:1)

“需要让它们公开,这会破坏封装”

不要将优秀的设计与icky可见性规则混为一谈。可见性规则令人困惑。实际上有两种正交的可见性 - 子类和客户端。我们为什么要从子类中隐藏任何东西并不完全清楚。但我们可以private

这是重要的。封装并不意味着隐藏。受保护和私有不是良好封装的重要组成部分。你可以做好所有公开的设计(例如Python的工作方式)。

受保护/私人的东西 - 主要是 - 关于知识产权管理:你是否愿意承诺(具有法律约束力,“在法庭上看见 - 如果不是工作”的方式) )到界面?如果您的软件开发涉及律师,那么您关心的是为您不承诺的事物添加保护和私有。

如果您不需要应对律师,请考虑正确封装,但请将所有内容公之于众。

答案 2 :(得分:0)

很抱歉,“我的表格”中你的意思并不清楚 - 你的表格和两个班级之间的关系是什么?如果您的类是同一项目中的控件,并且您想要从表单访问属性,则应使用“internal”关键字。

答案 3 :(得分:0)

至少有三种方法可以限制谁可以使用特定类实例的某些特定实例方法:

  1. 将方法定义为`protected`,`internal`或`private`。在第一种情况下,实例方法只能在同一实例的派生类方法中使用;在第二种情况下,程序集中的所有类都可以访问这些方法,但外部的类不会;在第三种情况下,除非它们的代码嵌套在声明类中,否则外部类(即使是同一程序集中的派生类)也不会具有访问权限。
  2. 将方法定义为`public`,但是让创建实例的类保持私有并且永远不会将它们暴露给外部世界。任何想要在对象上调用实例方法的人都必须有一个实例来调用它。如果一个类包含实例但从未公开对它们的直接引用,则可以在这些实例上使用的唯一实例方法将是保持类自身使用的实例。
  3. 将方法定义为`public`,但是有一个构造函数,它接受一个位置,私有方法的一个或多个委托可以存储在该位置。访问这些代理的代码将能够调用由此引用的方法,但其他代码将不会(除了使用我认为只能在完全信任的情况下使用的反射)。

如果非完全信任场景中的反射允许未绑定的委托绑定到任意对象实例,则可以使用嵌套类来强化#3,以便必须访问private字段才能获得非法访问权限到private函数;在完全信任的情况下肯定会被禁止。