Java開發筆記(四十五)成員屬性與成員方法

前面介紹了許多數據類型,除了基本類型如整型int、雙精度型double、布爾型boolean以外,還有高級一些的如包裝整型Integer、字符串類型String、本地日期類型LocalDate等等,那麼這些數據類型爲什麼會分紅基本和高級兩種呢?這與編程語言的發展歷程息息相關,像中文、英文這些是人類社會的天然語言,而計算機可以識別的是機器語言,可是機器語言全爲以0和1表達的二進制串,看起來彷彿天書通常,讀都讀不懂,更別說寫出來了。爲了方便程序員也能操縱計算機,科學家把機器語言所表達的一些常見操做概括起來,分別使用特定的英語單詞來代替它們,例如MOV表示移動指令,ADD表示加法指令,SUB表示減法指令,MUL表示乘法指令,DIV表示除法指令等等。那時的數字則放在一個個寄存器中,所謂寄存器指的是某個存儲單元,每一個存儲單位可保存8位的二進制數,計算機中有八個通用的8位寄存器,分別是AH、AL、BH、BL、CH、CL、DH、DL。對於彙編語言來講,指令至關於操做符,寄存器至關於變量,此時沒有明確的數據類型之分,由於全部數據都是8位二進制數。雖然彙編語言比起機器語言來講,總算能被程序員看懂了,可是它的表達手段無疑很原始,因此彙編語言屬於計算機的低級語言。
然而彙編語言實在是過低級了,每次操做只能處理8位的二進制數,若是須要對很大的數字進行運算,彙編語言就得把大數運算拆分紅若干條指令處理。好比300與400相加,因爲300和400各需16位二進制數存放,所以它們的加法運算至少要分解爲三條加法指令;第一條是兩個數字的前面8位相加,第二條是兩個數字的後面8位相加,假若第二條加法之和超出255,則第三條還得給第一條的運算結果加一。可見大數相加已然如此繁瑣,大數相乘或者相除只會更加麻煩,爲了進一步簡化彙編語言,科學家又發明了以C語言爲表明的中級語言。C語言相對彙編語言的一個顯著進步,是把基本數據類型分門別類,推出了整型int、長整型long、浮點型float、雙精度型double、布爾型boolean等類型,每種基本類型都有明確的數字表達範圍,若在精度要求範圍以內開展加減乘除四則運算,只要書寫一次帶有運算符+、-、*、/的操做語句便可。正由於C語言屏蔽了不一樣數字類型在機器存儲上的差別,使得程序員可以專一於業務邏輯層面的編碼,從而促進了軟件行業的飛躍發展。
但是C語言僅僅劃分了基本的數據類型,若想處理更復雜的數據,就得定義新的結構體struct來存放複雜數據。這個結構體只是若干基本類型變量的堆砌,對結構體的操做等同於修改它的某個變量值,致使程序代碼嚴重依賴於最初的編碼人員,由於一個變量的含義每每只有他才知道,要是換了別人接手,得費老大的勁才能搞清楚某變量的涵義。因而科學家又設計了基於C的C++語言,C++提供了全新的類class意圖替代結構體struct,在class這個類裏面,變量被稱做類的屬性,函數被稱做類的方法,外部經過類的方法來讀寫類的屬性。這樣作的好處是顯而易見的,首先方法名能夠起個有意義的名稱;其次方法擁有輸入參數和輸出參數,可以處理更多的信息量;再次方法內部容許編寫複雜的業務邏輯,而不只限於單純讀寫某個屬性。如此一來,C++經過類便能定義和處理接近於天然界的事物概念,比如你媽催你找對象,對象可不是幾塊布縫製而成的洋娃娃,而是有血有肉能說會唱的伊人。C語言的結構體猶如不會動的洋娃娃,C++的類才與活生生的伊人相仿,所以工業界將C++稱做面向對象的編程語言,並納入高級語言的行列。
至於Java語言,則是承繼了C++的衣鉢,一方面保留了面向對象的精髓,另外一方面去掉了繁瑣的指針操做,即所謂的取其精華、去其糟粕。Java中的類一樣使用關鍵字class來表達,類內部的各類要素被稱爲類的成員,例如類的屬性也叫作成員屬性,類的方法也叫作成員方法。先前介紹的那些高級類型諸如Integer、String、LocalDate,它們的源碼都是經過class定義的,包含的成員屬性與成員方法各不相同。譬如Integer擁有一個整型的成員屬性,還有包括equals在內的幾個成員方法;String擁有一個字符數組的成員屬性,還有包括indexOf、replace在內的若干個成員方法;LocalDate擁有整型的年、月、日這三個成員屬性,還包括getDayOfMonth、plusMonths、isLeapYear等等成員方法。不過Java開發包提供的高級類型畢竟是有限的,要想知足更加具體的業務需求,則需由程序員本身定義新的數據類型,也就是從頭編寫新的class。
早在本系列文章的一開始,便給出了一個以下所示的簡單類定義:html

package com.donghan.nanjun.dangyang; // 東漢帝國南郡當陽縣

public class Maicheng {
}

以上的類定義代碼,開頭的public表示這個類對外開放,class是類的標識符,Maicheng則是類的名稱,其後的左右花括號內部用來填寫類的各類成員。如今往類內部添加幾個成員屬性,把它變成一個有實際意義的事物,就像下面的橘子類代碼,定義了橘子的名稱、重量、是否成熟、產地等物品特徵:java

//演示如何定義類的屬性
public class OrangeSimple {

	// 定義了橘子的名稱
	public String name;
	// 定義了橘子的重量
	public double weight;
	// 定義了橘子是否成熟。true表示成熟,false表示未成熟
	public boolean isRipe;
	// 定義了橘子的產地
	public String place;
}

上面的類代碼合計定義了橘子的四種屬性,接下來外部先利用關鍵字new建立橘子類的一個實例,再經過形如「實例名.屬性名」的格式訪問該實例的各個屬性,具體的操做代碼以下所示:程序員

	// 演示OrangeSimple類的調用
	private static void testSimple() {
		// 建立OrangeSimple的一個實例
		OrangeSimple orange = new OrangeSimple();
		orange.name = "橘子"; // 設置名稱屬性
		orange.place = "淮南"; // 設置產地屬性
		orange.isRipe = true; // 設置是否成熟的屬性
		orange.weight = 200; // 設置重量屬性
	}

 

但是這個OrangeSimple類只有成員屬性,沒有成員方法,充其量是C語言時代的孑遺,還得補充幾個成員方法,才配得上高級語言的身份。而且使用成員方法至少有下列幾項好處:編程


一、把屬性的讀寫操做分開。
好比經過get***方法獲取某個屬性的值,經過set***方法修改某個屬性的值,此時屬性定義的前綴須要把public改成private,表示該屬性不對外開放。以名稱字段name爲例,新增getName方法用於讀取橘子的名稱,新增setName方法用於變動橘子的名稱,另外把name屬性的開放性改成private,修改以後的代碼片斷以下:數組

	// 定義了橘子的名稱
	private String name;

	// 設置橘子的名稱
	public void setName(String inputName) {
		name = inputName;
	}

	// 獲取橘子的名稱
	public String getName() {
		return name;
	}

  

二、一個方法能夠同時修改多個屬性的值。
古人云「橘生淮南則爲橘,生於淮北則爲枳」,可見橘子的名稱與其產地是有關聯的,一旦產地字段發生變動,則橘子名稱也可能跟着變化。那麼依照「橘生淮北則爲枳」的規則,可將產地設置方法setPlace更改成如下邏輯:編程語言

	// 設置橘子的產地
	public void setPlace(String inputPlace) {
		place = inputPlace;
		if (place.equals("淮北")) {
			name = "枳子";
		} else {
			name = "橘子";
		}
	}

  


三、一個方法能夠同時輸出多個屬性的值。
當某個類型擁有多個屬性的時候,最好可以一次性輸出全部屬性值。譬如本地日期類型LocalDate,其內部包含年、月、日三種屬性,調用日期實例toString方法,便可返回完整的年月日字符串。對於橘子類型來講,也可在該類的內部定義一個toString方法,把該類的全部屬性值拼接成字符串並返回,就像下面代碼示範的那樣:函數

	// 輸出各屬性字段的取值
	public String toString() {
		String desc = String.format("這個%s的重量是%f克,%s成熟,產地是%s。", 
				name, weight, isRipe?"已":"未", place);
		return desc;
	}

  


綜合上述的幾點修改,獲得添加了成員方法的OrangeMember類,它的完整定義代碼以下所示:編碼

//演示類的封裝,對成員屬性和成員方法的定義
public class OrangeMember {
	
	// 定義了橘子的名稱
	private String name;
	// 定義了橘子的重量
	private double weight;
	// 定義了橘子是否成熟。true表示成熟,false表示未成熟
	private boolean isRipe;
	// 定義了橘子的產地
	private String place;
	
	// 設置橘子的產地
	public void setPlace(String inputPlace) {
		place = inputPlace;
		if (place.equals("淮北")) {
			name = "枳子";
		} else {
			name = "橘子";
		}
	}

	// 獲取橘子的產地
	public String getPlace() {
		return place;
	}
	
	// 設置橘子的名稱
	public void setName(String inputName) {
		name = inputName;
	}

	// 獲取橘子的名稱
	public String getName() {
		return name;
	}

	// 設置橘子的重量
	public void setWeight(double inputWeight) {
		weight = inputWeight;
	}

	// 獲取橘子的重量
	public double getWeight() {
		return weight;
	}

	// 設置橘子是否成熟
	public void setRipe(boolean inputRipe) {
		isRipe = inputRipe;
	}

	// 獲取橘子是否成熟
	public boolean getRipe() {
		return isRipe;
	}

	// 輸出各屬性字段的取值
	public String toString() {
		String desc = String.format("這個%s的重量是%f克,%s成熟,產地是%s。", 
				name, weight, isRipe?"已":"未", place);
		return desc;
	}
}

而後外部在建立該類的實例以後,便能調用實例的成員方法進行相應操做了。下面是外部使用OrangeMember類型的代碼例子:spa

	// 演示OrangeMember類的調用
	private static void testMember() {
		// 建立OrangeMember的一個實例
		OrangeMember orange = new OrangeMember();
		orange.setName("橘子"); // 調用名稱設置方法
		orange.setPlace("淮南"); // 調用產地設置方法
		orange.setRipe(true); // 調用是否成熟的設置方法
		orange.setWeight(200); // 調用重量設置方法
		// 打印該實例的詳細信息
		System.out.println(orange.toString());
	}

 

運行上面的例子代碼,獲得以下的日誌信息,可見OrangeMember類的幾個成員方法正常工做:設計

這個橘子的重量是200.000000克,已成熟,產地是淮南。

  

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

相關文章
相關標籤/搜索