我很困惑爲什麼課程組成了public
和protected
方法/變量。 爲什麼只有擴展類可以訪問protected
方法/變量?其他人可以幫我指導public
和protected
之間的區別和它的功能。公共vs受保護
公共vs受保護
回答
爲什麼只有派生類可以訪問受保護的成員?
因爲這是定義的「保護」。受保護成員的可訪問性域是類及其派生類。
也許你打算問:
爲什麼我不總是甚至訪問受保護的成員,當我在派生類中?
這很複雜。有關詳細解釋,請參閱我的六部分系列「爲什麼我不能從派生類訪問受保護的成員?」
假設這是在Java語言環境中。
public
- 可以從任何類protected
訪問 - 可以從子/派生類中只有
那麼,爲什麼他們這樣做是因爲這只是他們是什麼進行訪問。我想也許你想知道爲什麼要這樣做。簡單的答案是因爲派生類需要訪問它們,而外部類不需要。
訪問修飾符(以及public
和protected
,有private
,internal
和protected internal
)是保持代碼可以理解,儘可能減少錯誤的手段。
有些語言沒有任何形式的封裝。在他們最極端的情況下,任何代碼都可以改變任何數據。有紀律的編碼器會減少給定類型的數據被操縱的位置數量,但它可能仍然不是顯而易見的可能使對象*處於不同狀態的所有操作組合。當他們的代碼被用作別人代碼的一部分時,情況會變得更糟。
訪問修飾符幫助我們處理這個問題。我們默認會員是私人的。然後,成員可以訪問的唯一位置就是類本身。這意味着:
- 唯一的錯誤在於如何操縱它們,是在課堂內部。
- 唯一需要擔心保持這些成員處於一致狀態的代碼是在類中,並且代碼不必擔心其他代碼可能會使其失敗。
- 通過查看一個類的定義(通常在一個文件中並且很少在兩個以上),可以獲得這些字段被操縱的每種方式的完整圖片。
這使我們更容易編碼。
當然,一切都是私人的課程並不是很有用。我們通常不得不讓一些成員公開。通常情況下,我們的領域是私人的,一些有用的方法是私人的,然後一些公共方法和屬性使用這些方法。我們仍然可以通過檢查一個班級來檢查私人成員的所有可能的操作,儘管我們已經開放了向其他班級調用這些班級的成員。因此,這些成員爲我們提供了類內部和外部的代碼之間的接口,這是我們保護類錯誤狀態的邊界,同時爲其他代碼提供有用的功能。
現在應該清楚,我們不公開某些東西,除非需要,但我們確實需要有用的工作才能成爲可能。
讓會員受到保護讓我們處於中間地帶。我們仍然在減少可以操縱的地方,但不是那麼嚴重。通常,這樣做是爲了讓派生類可以將自己的機制提供給基本中定義的常規接口。
使用它的案例較少,因爲通常情況下我們可以將事物保密 - 這更安全 - 或必須公開纔能有用。其中最常見的情況是公共成員提供功能的位置以及受保護的定義方式來實現它。例如,HttpEncoder
提供了幾種處理HTML編碼字符串問題的方法,但是有兩種受保護的抽象方法可以派生類重寫以提供幾種不同方法的通用功能。外部類不需要訪問這些類,但派生類可以。
一個實際的例子。假設我們有一個實現INotifyPropertyChanging
的基類。這個接口意味着它必須跟蹤處理器,並在屬性即將改變時引發事件。
我們不希望外界班,以提高該事件,因爲這不是他們的業務,並讓他們這樣做僅僅是將導致錯誤。
我們必須讓派生類可以這樣做,因爲它們可以定義基類不知道的屬性。
因此,我們在此基類中定義一個引發事件的受保護方法。外部類不能調用它(降低被錯誤調用的風險),但派生類可以(能夠完成他們需要做的工作)。
*來自面向對象的背景的人甚至可能不會將這些數據視爲「對象」。
我也一直在通過public
和protected
混淆。
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();
}
}
- 1. Java受保護字段vs公共獲取者
- 2. 受保護/公共變量與Vs. F#中的閉包#
- 3. C++類(公共,私有和受保護)
- 4. 公共getter,帶CodeDOM的受保護setter
- 5. C++保護/公共重載
- 6. 訪問受保護方法中的公共變量
- 7. PHP類常量 - 公共,私有還是受保護的?
- 8. 僅獲取受保護方法和公共方法的MethodInfo?
- 9. 從受保護的嵌套類繼承的公共嵌套類?
- 10. 與公共,私人和受保護區別
- 11. javadoc所有 - 私人,公共和受保護的成員
- 12. PHP:設置私人,受保護,在公共界面?
- 13. VB.NET:屬性與公共getter和受保護的setter
- 14. 公共/受保護/私有繼承問題
- 15. 屬性公共和私人但不受保護?
- 16. python中的私有公共受保護訪問說明符
- 17. NHibernate的例外:方法Add應該是「公共/受保護的虛擬」或「受保護的內部虛擬」
- 18. 公開一個受保護的屬性
- 19. 受保護的共享內存?
- 20. 窗口 - 受保護的共享內存
- 21. 訪問共享文件夾(受保護)
- 22. 受保護的內部屬性vs受保護的屬性和Resharper
- 23. 公共保護是什麼意思?
- 24. 保護公共API(不需要註冊)
- 25. 公共私人和保護在objective-c
- 26. 保護鏈接公共下載
- 27. 保護共享用戶的公式
- 28. 範圍的私有,保護和公共
- 29. 將受保護訪問者的按鈕單擊事件移至公共
- 30. 爲什麼在Obejct類中有公共方法,它們可能受到保護?
在其編程語言? – 2012-01-18 11:05:08
你還沒有指定你在說什麼語言 - 而「爲什麼」從根本上可能被回答「因爲這是規範說的」......你應該澄清你的問題。 – 2012-01-18 11:05:16
編程語言無關緊要。公共財產將在課外提供。受保護的財產將不在課堂外提供,但將在兒童課程中提供。與方法一樣,這是OOP編程的一種方式。在谷歌的OOP閱讀更多。 – Slavic 2012-01-18 11:08:14