公有 vs 受保护的

6

我对类为什么由publicprotected方法/变量组成感到困惑。 为什么只有扩展类可以访问protected方法/变量? 有人能帮我解释一下publicprotected之间的区别及其功能吗?


2
用哪种编程语言? - Oliver Charlesworth
3
编程语言并不重要。公共属性将在类外可用。受保护的属性将不会在类外可用,但将在子类中可用。同样,方法也是如此,这是面向对象编程的一种方式。在谷歌上阅读更多关于面向对象编程的内容。 - Slavic
2
@Slavic:一般原则可能相似,但不同语言之间可能存在特定的语义差异。 - Oliver Charlesworth
1
一般原则是所需的,Oli,而不是一般原则,而是一般面向对象编程概念。 - Slavic
2
如果你想要简短的答案,它会使编程更加健壮。长一点的回答,请在谷歌上阅读面向对象编程材料。 - Slavic
显示剩余7条评论
3个回答

9
为什么只有派生类可以访问受保护的成员变量?
因为这是“protected”关键字的定义。受保护成员变量的可访问域是该类及其派生类。
也许您的意图是询问:
为什么即使我在派生类中,有时也不能访问受保护的成员变量呢?
这很复杂。详细解释请参见我的六篇系列文章“为什么我不能从派生类中访问受保护的成员变量?”

http://blogs.msdn.com/b/ericlippert/archive/tags/protected/


坏链接...... - undefined

4
好的,为什么要这么做呢?因为这是它们存在的原因。也许你想知道为什么需要这样做。简单的回答是,派生类需要访问它们,而外部类不需要。
访问修饰符(除了public和protected,还有private、internal和protected internal)是尽可能使代码易懂以减少错误的一种方式。
有一些语言没有任何封装形式。在最极端情况下,任何代码都可以改变任何数据的任何部分。遵循规范的程序员会减少给定类型数据操作的数量,但可能仍然不清楚所有可能导致对象*处于不同状态的操作组合。当他们的代码作为别人的代码的一部分时,情况会变得更糟。
访问修饰符可以帮助我们解决这个问题。我们默认将成员设为私有。那么这个成员唯一能够访问的地方就是在类本身内。这意味着:
1. 操作中出现失误的唯一位置就在类内。 2. 唯一需要考虑如何保持这些成员处于一致状态的代码位于类内,而且该代码不必担心其他代码会干扰这一点。 3. 通过查看一个类的定义,我们可以获得这些字段被操作的所有方法的完整图片,这通常在一个文件中,并且很少超过两个文件。
这使我们更容易编写良好的代码。
当然,所有成员都是私有的类并不是很有用。通常我们需要让一些成员公开。通常我们的字段是私有的,有一些有用的方法也是私有的,然后一些公共方法和属性使用它们。虽然我们已经向其他类开放了调用执行此操作的成员,但仍然可以通过检查一个类来检查私有成员的所有可能操作。因此,这些成员为我们提供了在类内外部之间的界面,我们通过这个界面保护类的状态免受错误,同时为其他代码提供有用的功能。
现在应该清楚了,除非必须如此,否则我们不会将某些东西设为公共的,但我们确实需要这样做才能进行有用的工作。
将成员设置为protected会给我们带来一个折衷方案。我们仍在减少可以操作某些内容的位置,但不那么严格。通常,这是为了派生类可以为基类定义的一般接口提供自己的机制。
由于通常要么将东西保持私有(更安全),要么必须公开才能有用,因此使用情况较少。其中最常见的情况之一是,公共成员提供功能,而protected定义了实现该功能的方法。例如,HttpEncoder提供了几种处理编码HTML字符串问题的方法,但有两个受保护的抽象方法可以由派生类重写以提供多个不同方法所需的功能。外部类不需要访问这些方法,但派生类需要访问它们。
一个实际的例子。假设我们有一个实现了INotifyPropertyChanging接口的基类。这个接口意味着它必须跟踪PropertyChangingEventHandler处理程序,并在属性即将更改时触发事件。
我们不希望外部类引发该事件,因为那不是它们的职责,让它们这样做只会导致错误。
我们必须让派生类这样做,因为它们可能定义自己的属性,而基类不知道。
因此,在这个基类中定义一个受保护的方法来触发事件。外部类不能调用它(减少了被错误调用的风险),但派生类可以(能够完成它们需要做的工作)。
*来自面向对象背景的人们甚至可能不认为这些数据片段是“对象”。

术语“outside classes”的含义在这里并不清楚。派生类通常位于定义受保护成员的类/文件/包/模块/程序集之外。此外,有很好的论据认为,由于受保护和公共都逃逸了封装并公开了API,因此不需要前者,它只会引起问题。(人们已经知道编写一个派生类,其中包含调用所需的受保护方法的公共方法。)请参见,例如,https://in.relation.to/2011/04/28/introduction-to-ceylon-part-2/(搜索“protected”) - undefined

3

假设这是在类似Java的语言上下文中。

  • public - 可以从任何类访问
  • protected - 仅限于子/派生类访问

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接