Java開發筆記(五十)幾種開放性修飾符

前面介紹子類繼承父類的時候,提到了public(公共)和private(私有)兩個修飾符,其中public表示它所修飾的實體是容許外部訪問的;而private表示它所修飾的實體不容許外部訪問,只能在當前類內部訪問private成員,即使是子類也不能訪問父類的私有成員。這種狀況就使人產生了困惑,私人財產固然不會給外人,但是爲啥連兒子都沒法動用老子的財物呢?看起來public與private的規則不甚合理,畢竟兒子同外人仍是有區別的呀,所謂親疏有別、一家人不說兩家話。爲此Java設計了新的修飾符名叫protected,意思是受保護的,其實就是給子類們網開一面,凡是被protected修飾的成員,外部仍然不可訪問,惟有從當前類派生而來的子類能夠訪問。那麼對於受保護的成員來講,它對外部而言如同私有成員同樣不能訪問,它對子類而言如同公共成員同樣可以訪問。
固然,引入protected不只僅是面子上好看,還帶來了實實在在的好處。好比以前編寫鴨子類繼承鳥類的時候,發現性別名稱字段須要由「雄/雌」改成家禽通用的「公/母」,當時嘗試了下列的兩種寫法:
一、在Duck類裏面從新定義與父類同名的屬性字段sexName,這樣沒有變動外部對sexName的訪問權限,可是須要重寫與該字段有關的全部方法。
二、把Bird類的sexName改成使用public修飾,此時新的鴨子類DuckPublic無需所有重寫相關方法,但同時外部變得可以直接讀寫sexName字段,從而破壞了原來Bird類對該字段的良好封裝。
既要保持外部的訪問權限不變,又要避免子類冗餘的方法重載,這兩個願景看似魚與熊掌不可兼得。如今有了修飾符protected,本來自相矛盾的問題立馬迎刃而解,具體的解決步驟說明以下:
首先給Bird類的sexName屬性添加protected修飾,表示該字段是受保護的成員屬性,只可在本家族內部使用,不可對外部開放。因而改寫後的Bird類代碼片斷以下所示:html

public class Bird {

	// 此處省略其它成員的定義……
	
	// 定義鳥的性別名稱
	//private String sexName; // 與Duck搭配使用
	//public String sexName; // 與DuckPublic搭配使用
	protected String sexName; // 與DuckProtected搭配使用
	
	// 此處省略其它成員的定義……
}

接着編寫與之配套的鴨子類代碼DuckProtected,並重載setSexType方法,將sexName字段的取值改成「公」或者「母」。詳細的DuckProtected類定義代碼示例以下:java

// 演示關鍵字protected的用法
public class DuckProtected extends Bird {

	public DuckProtected(String name, int sex) {
		super(name, sex, "嘎嘎");
	}

	public void setSexType(int sexType) {
		super.setSexType(sexType);
		// 若想對父類的屬性直接賦值,又不想對外開放該屬性,則可將父類的屬性從private改成protected
		// 被protected修飾的成員,表示受保護,它容許子類訪問,但不容許外部訪問。
		// 假若父類的屬性被protected修飾,則子類能夠直接讀寫該屬性;
		// 假若父類的方法被protected修飾,則子類能夠直接讀寫該方法;
		// 所謂讀方法,就是方法的調用操做;所謂寫方法,就是方法的重載操做。
		sexName = (sexType==0) ? "公" : "母";
		//super.sexName = (sexType==0) ? "公" : "母";
	}
}

注意,被protected修飾的成員屬性,對於子類來講可讀可寫,既能把原值讀出來也能把新值寫進去。然而被protected修飾的成員方法,又何來所謂的讀寫操做?確實,方法不像字段,它沒有讀方法和寫方法的概念,只有方法調用和方法重載的說法。那麼對於方法而言,方法調用可看做是一種讀操做,而方法重載可看做是一種寫操做,瞅瞅「重寫」二字帶着一個「寫」字嘛。編程

從公共的public,到私有的private,再到受保護的protected,正好三個單詞都以字母p開頭,3p系列這下總算湊齊了吧?但是還有一種狀況,就是某個實體不加任何的開放性修飾符。嗯哼,Java竟然容許某個東西既非公共又非私有也非受保護,那這東東究竟要給誰使用?不加修飾符的話,其實Java也給它分配了一個默認的開放性,譬如某人在美國出生,他便自動得到了美國國籍;某人在北京出生,理應要得到北京戶口,這個國籍或戶口便可當作是默認的歸屬地。擁有北京戶口的人,能夠優先享受當地的教育、醫療等資源,爲的就是他/她是北京人,因此當地資源對他/她夠友好。在Java的編程世界之中,「當地」指的是同一個package(代碼包),既然你們生活在同一個package的屋檐下面,就應當互相幫助互相愛護。於是未加3p修飾符的實體,表示它屬於當地資源,對當地人很友好,凡有當地戶口的都容許訪問它。
如此算來,Java實際上存在四種開放性,根據開放程度的大小排序,依次分別爲:
public:公共的,容許全部人訪問;
無修飾符:友好的,容許當地人訪問;
protected:受保護的,容許本家族訪問,包括自身及其子類;
private:私有的,只有自身能夠訪問。設計



更多Java技術文章參見《Java開發筆記(序)章節目錄htm

相關文章
相關標籤/搜索