公共与受保护

Posted

技术标签:

【中文标题】公共与受保护【英文标题】:Public vs Protected 【发布时间】:2012-02-13 02:31:27 【问题描述】:

我很困惑为什么类由publicprotected 方法/变量组成。 为什么只有扩展类可以访问protected 方法/变量?其他人可以帮助我了解publicprotected 之间的区别及其功能。

【问题讨论】:

使用哪种编程语言? 您尚未指定您正在谈论的语言 - “为什么”从根本上可能是“因为这就是规范所说的”......你应该澄清你的问题。 编程语言无关紧要。公共财产将在课堂外可用。受保护的属性在类外不可用,但在子类中可用。方法也是如此,这是 OOP 编程的一种工作方式。在 google 上阅读有关 OOP 的更多信息。 @Slavic:大体原理可能相似,但不同语言之间可能存在特定的语义差异。 如果您想要简短的答案,它可以实现更强大的编码。长答案,请阅读google上的OOP材料。 【参考方案1】:

为什么只有派生类才能访问受保护的成员?

因为那是“受保护”的定义。受保护成员的可访问域是类及其派生类。

也许你想问:

为什么即使在派生类中,我也不能始终访问受保护的成员?

这很复杂。有关详细说明,请参阅我的六部分系列“为什么我不能从派生类访问受保护的成员?”

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

【讨论】:

【参考方案2】:

嗯,他们这样做是因为这就是他们的目的。我想也许你想知道为什么一个人可能想要。简单的答案是因为派生类需要访问它们,而外部类不需要。

访问修饰符(以及publicprotected,还有privateinternalprotected internal)是一种使代码尽可能易于理解以减少错误的方法。

有些语言没有任何形式的封装。在最极端的情况下,任何代码都可以更改任何数据的任何部分。训练有素的编码人员将减少对给定类型数据进行操作的位置数量,但可能仍然不明显所有可能使对象*处于不同状态的操作组合。当他们的代码被用作其他人代码的一部分时,情况会变得更糟。

访问修饰符帮助我们处理这个问题。我们默认将成员设为私有。那么唯一可以访问成员的地方就是类本身。这意味着:

    在如何操作它们时,唯一的错误可能是在类内部。 唯一需要担心使这些成员保持一致状态的代码位于类内部,并且该代码不必担心其他代码可能会破坏它。 您可以通过查看一个类的定义来全面了解这些字段的各种操作方式,该定义通常在一个文件中,很少超过两个。

这让我们更容易编写好代码。

当然,所有内容都是私有的类并不是很有用。我们通常必须让一些成员公开。通常我们的字段是私有的,一些有用的方法是私有的,然后一些公共方法和属性使用这些。我们仍然可以通过只检查一个类来检查对私有成员的所有可能操作,尽管我们已经开放了调用其他类的成员。因此,这些成员为我们提供了类内部和外部代码之间的接口,这是我们保护类状态免受错误同时为其他代码提供有用功能的边界。

现在应该很清楚,我们不会公开某些东西,除非我们需要,但我们确实需要让有用的工作成为可能。

使成员受保护为我们提供了一个中间立场。我们仍在减少一些可以被操纵的地方,但不是那么严重。通常,这样做是为了让派生类可以为基类中定义的通用接口提供自己的机制。

使用它的情况较少,因为通常我们可以将内容保密 - 这更安全 - 或者必须公开才能有用。最常见的情况之一是公共成员提供功能而受保护的定义方式来实现它。例如,HttpEncoder 提供了几种处理 html 字符串编码问题的方法,但是派生类覆盖了两个受保护的抽象方法,以提供几种不同方法共有的功能。外部类不需要访问这些,但派生类可以。

一个实际的例子。假设我们有一个实现INotifyPropertyChanging 的基类。此接口意味着它必须跟踪PropertyChangingEventHandler 处理程序,并在属性即将更改时引发事件。

我们不希望外部班级引发该事件,因为这不关他们的事,让他们这样做只会导致错误。

我们必须让派生类这样做,因为它们可能定义自己的属性,而基类不知道。

因此,我们在这个引发事件的基类中定义了一个受保护的方法。外部类不能调用它(降低被错误调用的风险),但派生类可以(能够完成他们需要做的工作)。

*具有面向对象背景的人甚至可能不认为这些数据是“对象”。

【讨论】:

【参考方案3】:

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

public - 可以从任何类访问 protected - 只能从子/派生类访问

【讨论】:

以上是关于公共与受保护的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C - 私有与受保护与公共

typescript 公共,私有与受保护的修饰符

受保护的内部属性与受保护的属性和 Resharper

如何将 ACL 与受保护的资源连接起来?

静态类与受保护的构造函数

将 make_shared 与受保护的构造函数 + 抽象接口一起使用