2012-01-18 91 views
2

我很困惑为什么课程组成了publicprotected方法/变量。 为什么只有扩展类可以访问protected方法/变量?其他人可以帮我指导publicprotected之间的区别和它的功能。公共vs受保护

+2

在其编程语言? – 2012-01-18 11:05:08

+1

你还没有指定你在说什么语言 - 而“为什么”从根本上可能被回答“因为这是规范说的”......你应该澄清你的问题。 – 2012-01-18 11:05:16

+1

编程语言无关紧要。公共财产将在课外提供。受保护的财产将不在课堂外提供,但将在儿童课程中提供。与方法一样,这是OOP编程的一种方式。在谷歌的OOP阅读更多。 – Slavic 2012-01-18 11:08:14

回答

8

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

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

也许你打算问:

为什么我总是甚至访问受保护的成员,当我在派生类中?

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

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

1

假设这是在Java语言环境中。

  • public - 可以从任何类
  • protected访问 - 可以从子/派生类中只有
3

那么,为什么他们这样做是因为这只是他们是什么进行访问。我想也许你想知道为什么要这样做。简单的答案是因为派生类需要访问它们,而外部类不需要。

访问修饰符(以及publicprotected,有privateinternalprotected internal)是保持代码可以理解,尽可能减少错误的手段。

有些语言没有任何形式的封装。在他们最极端的情况下,任何代码都可以改变任何数据。有纪律的编码器会减少给定类型的数据被操纵的位置数量,但它可能仍然不是显而易见的可能使对象*处于不同状态的所有操作组合。当他们的代码被用作别人代码的一部分时,情况会变得更糟。

访问修饰符帮助我们处理这个问题。我们默认会员是私人的。然后,成员可以访问的唯一位置就是类本身。这意味着:

  1. 唯一的错误在于如何操纵它们,是在课堂内部。
  2. 唯一需要担心保持这些成员处于一致状态的代码是在类中,并且代码不必担心其他代码可能会使其失败。
  3. 通过查看一个类的定义(通常在一个文件中并且很少在两个以上),可以获得这些字段被操纵的每种方式的完整图片。

这使我们更容易编码。

当然,一切都是私人的课程并不是很有用。我们通常不得不让一些成员公开。通常情况下,我们的领域是私人的,一些有用的方法是私人的,然后一些公共方法和属性使用这些方法。我们仍然可以通过检查一个班级来检查私人成员的所有可能的操作,尽管我们已经开放了向其他班级调用这些班级的成员。因此,这些成员为我们提供了类内部和外部的代码之间的接口,这是我们保护类错误状态的边界,同时为其他代码提供有用的功能。

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

让会员受到保护让我们处于中间地带。我们仍然在减少可以操纵的地方,但不是那么严重。通常,这样做是为了让派生类可以将自己的机制提供给基本中定义的常规接口。

使用它的案例较少,因为通常情况下我们可以将事物保密 - 这更安全 - 或必须公开才能有用。其中最常见的情况是公共成员提供功能的位置以及受保护的定义方式来实现它。例如,HttpEncoder提供了几种处理HTML编码字符串问题的方法,但是有两种受保护的抽象方法可以派生类重写以提供几种不同方法的通用功能。外部类不需要访问这些类,但派生类可以。

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

我们不希望外界班,以提高该事件,因为这不是他们的业务,并让他们这样做仅仅是将导致错误。

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

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

*来自面向对象的背景的人甚至可能不会将这些数据视为“对象”。

2

我也一直在通过publicprotected混淆。

A protected变量(或方法)不能从实例中访问(使用new创建);它只能从扩展超类的子类访问(使用extends扩展)。

这类似于Java的例子应该有助于澄清的差异。

// Super-Class: Vehicle 
public class Vehicle { 

    // (1) I'm a protected variable 
    protected String engine = "engine"; 

} 

// Sub-Class: Car 
public class Car extends Vehicle { 

    public String printEngineSuccess() { 
    // (2) We can print a protected variable, 
    // from within this class because it extends 
    // the super-class `Vehicle`. 
    System.out.println(super.engine); // --> SUCCESS 
    } 

    public String printEngineError() { 
    // (3) We can NOT print a protected variable, 
    // from a `new` instance of the super-class `Vehicle`. 
    Vehicle vehicle = new Vehicle(); 
    System.out.println(vehicle.engine); // --> ERROR 
    } 

    public static void main (Strings[] args) { 
    printEngineSuccess(); 
    printEngineError(); 
    } 
}