我很困惑为什么类由public
和protected
方法/变量组成。
为什么只有扩展类才能访问protected
个方法/变量?其他人可以帮助我启发public
和protected
之间的区别及其功能。
答案 0 :(得分:9)
为什么只有派生类才能访问受保护的成员?
因为那是“受保护”的定义。受保护成员的可访问性域是类及其派生类。
也许你打算问:
即使我在派生类中,为什么不始终可以访问受保护的成员?
这很复杂。有关详细说明,请参阅我的六部分系列“为什么我不能从派生类访问受保护的成员?”
答案 1 :(得分:4)
那么,他们为什么这样做是因为这就是他们的目的。我想也许你想知道为什么一个人想要。简单的答案是因为派生类需要访问它们,而外部类则不需要访问它们。
访问修饰符(以及public
和protected
,private
,internal
和protected internal
)是保持代码可理解的方法可以减少错误。
有些语言没有任何形式的封装。在最极端的情况下,任何代码都可以更改任何数据。训练有素的编码器将减少操作给定类型数据的位置数量,但是可能仍然不明显所有可能使对象*处于不同状态的操作组合。当他们的代码被用作别人代码的一部分时,情况会变得更糟。
访问修饰符可以帮助我们处理这个问题。我们默认会员是私人的。然后可以访问成员的唯一位置是类本身。这意味着:
这使我们更容易编码。
当然,一切都是私人的课程并不是很有用。我们通常不得不让一些成员公开。通常我们将字段设为私有,一些有用的方法是私有的,然后一些公共方法和属性使用它们。我们仍然可以通过检查一个类来检查私有成员的所有可能的操作,尽管我们已经打开调用这样做的成员到其他类。因此,这些成员为我们提供了类内部和外部代码之间的接口,我们保护类的状态不会出错,同时为其他代码提供有用的功能。
现在应该很清楚,除非我们需要,否则我们不会公开,但我们确实需要有用的工作。
让会员受到保护可以为我们提供一个中间立场。我们仍然在减少可以操纵的地方,但不是那么重要。通常,这样做是为了使派生类可以为基础中定义的通用接口提供自己的机制。
使用它的情况较少,因为通常我们要么保持私有 - 这更安全 - 或者必须公开才有用。最常见的情况之一是公共成员提供功能的地方,受保护的定义是实现它的方法。例如,HttpEncoder
提供了几种处理HTML编码字符串问题的方法,但有两种受保护的抽象方法,派生类重写以提供几种不同方法共有的功能。外部类不需要访问它们,但派生类可以访问它们。
一个实际的例子。假设我们有一个实现INotifyPropertyChanging
的基类。此接口意味着它必须跟踪PropertyChangingEventHandler
处理程序,并在属性即将发生变化时引发事件。
我们不希望外部课程提出该事件,因为这不是他们的业务,让他们这样做只会导致错误。
我们必须让派生类这样做,因为它们可能会定义基类不知道的属性。
因此,我们在此基类中定义一个引发事件的受保护方法。外部类不能调用它(降低了被错误调用的风险),但派生类可以(能够完成他们需要做的工作)。
*来自面向对象背景的人可能甚至不认为这些数据是“对象”。
答案 2 :(得分:2)
我也被public
和protected
混淆了。
无法从实例(使用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();
}
}
答案 3 :(得分:1)
假设这是在Java语言的上下文中。
public
- 可以从任何班级访问protected
- 只能从子/派生类访问