protected(受到保護的)訪問指示符要求大家提前有所認識。首先應注意這樣一個事實:為繼續學習本書一直到繼承那一章之前的內容,並不一定需要先理解本小節的內容。但為了保持內容的完整,這兒仍然要對此進行簡要說明,並提供相關的例子。
protected關鍵字為我們引入了一種名為“繼承”的概念,它以現有的類為基礎,並在其中加入新的成員,同時不會對現有的類產生影響——我們將這種現有的類稱為“基礎類”或者“基本類”(Base Class)。亦可改變那個類現有成員的行為。對於從一個現有類的繼承,我們說自己的新類“擴展”(extends)了那個現有的類。如下所示:
class Foo extends Bar {
類定義剩余的部分看起來是完全相同的。
若新建一個包,並從另一個包內的某個類裡繼承,則唯一能夠訪問的成員就是原來那個包的public成員。當然,如果在相同的包裡進行繼承,那麼繼承獲得的包能夠訪問所有“友好”的成員。有些時候,基礎類的創建者喜歡提供一個特殊的成員,並允許訪問衍生類。這正是protected的工作。若往回引用5.2.2小節“public:接口訪問”的那個Cookie.java文件,則下面這個類就不能訪問“友好”的成員:
//: ChocolateChip.java // Can't access friendly member // in another class import c05.dessert.*; public class ChocolateChip extends Cookie { public ChocolateChip() { System.out.println( "ChocolateChip constructor"); } public static void main(String[] args) { ChocolateChip x = new ChocolateChip(); //! x.foo(); // Can't access foo } } ///:~
對於繼承,值得注意的一件有趣的事情是倘若方法foo()存在於類Cookie中,那麼它也會存在於從Cookie繼承的所有類中。但由於foo()在外部的包裡是“友好”的,所以我們不能使用它。當然,亦可將其變成public。但這樣一來,由於所有人都能自由訪問它,所以可能並非我們所希望的局面。若象下面這樣修改類Cookie:
public class Cookie { public Cookie() { System.out.println("Cookie constructor"); } protected void foo() { System.out.println("foo"); } }
那麼仍然能在包dessert裡“友好”地訪問foo(),但從Cookie繼承的其他東西亦可自由地訪問它。然而,它並非公共的(public)。