物件導向-static關鍵字

ZHOU_VIP發表於2017-05-06

static關鍵字的引入:


/*
	定義一個人類
	
	姓名和年齡都是變化的,這個我能接收,因為每個人的姓名和年齡是不同的。
	但是,我們現在選取的幾個人都是中國人,他們的國籍是一樣的。
	一樣的國籍,我每次建立物件,在堆記憶體都要開闢這樣的空間,
	我就覺得有點浪費了。怎麼辦呢? 
		針對多個物件有共同的這樣的成員變數值的時候,
		Java就提高了一個關鍵字來修飾:static。
*/
class Person {
	//姓名
	String name;
	//年齡
	int age;
	//國籍
	//String country;
	static String country;
	
	public Person(){}
	
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	public Person(String name,int age,String country) {
		this.name = name;
		this.age = age;
		this.country = country;
	}
	
	public void show() {
		System.out.println("姓名:"+name+",年齡:"+age+",國籍:"+country);
	}
}

class PersonDemo {
	public static void main(String[] args) {
		//建立物件1
		Person p1 = new Person("鄧麗君",16,"中國");
		p1.show();
		
		//建立物件2
		//Person p2 = new Person("楊冪",22,"中國");
		//p2.show();
		Person p2 = new Person("楊冪",22);
		p2.show();
		
		//建立物件3
		//Person p3 = new Person("劉亦菲",20,"中國");
		//p3.show();
		Person p3 = new Person("劉亦菲",20);
		p3.show();
		
		//------------------------------------------
		//這些物件共享同一個靜態修飾的成員
		p3.country = "美國";
		p3.show();//..."美國"
		p1.show();//..."美國"
		p2.show();//..."美國"
		
	}
}

static關鍵字的特點:


/*
	static的特點:(它可以修飾成員變數,還可以修飾成員方法)
		A:隨著類的載入而載入
			回想main方法。
		B:優先於物件存在
		C:被類的所有物件共享
			舉例:我們們班級的學生應該共用同一個班級編號。
			其實這個特點也是在告訴我們什麼時候使用靜態?
				如果某個成員變數是被所有物件共享的,那麼它就應該定義為靜態的。
			舉例:
				飲水機(用靜態修飾)
				水杯(不能用靜態修飾)
		D:可以通過類名呼叫
			其實它本身也可以通過物件名呼叫。
			推薦使用類名呼叫。
			
			靜態修飾的內容一般我們稱其為:與類相關的,類成員
*/
class Student {
	//非靜態變數
	int num = 10;
	
	//靜態變數
	static int num2 = 20;
}

class StudentDemo {
	public static void main(String[] args) {//main方法為什麼是靜態的,因為是被虛擬機器呼叫的,不用建立物件
		Student s = new Student();
		System.out.println(s.num);       //10
		
		System.out.println(Student.num2);//20,類名呼叫
		System.out.println(s.num2);      //20,也可以被物件名呼叫
	}
}

static的記憶體圖解:靜態的內容在方法區的靜態區


static關鍵字注意事項:


/*
	static關鍵字注意事項
		A:在靜態方法中是沒有this關鍵字的
			如何理解呢?
				靜態是隨著類的載入而載入,this是隨著物件的建立而存在。
				靜態比物件先存在。
		B:靜態方法只能訪問靜態的成員變數和靜態的成員方法
				靜態方法:
					成員變數:只能訪問靜態變數
					成員方法:只能訪問靜態成員方法
				非靜態方法:
					成員變數:可以是靜態的,也可以是非靜態的
					成員方法:可是是靜態的成員方法,也可以是非靜態的成員方法。
			簡單記:
				靜態只能訪問靜態。
*/


靜態方法只能訪問靜態的成員變數和靜態的成員方法:



在靜態方法中是沒有this關鍵字的:


靜態變數和成員變數的區別

A:所屬不同

    靜態變數:屬於類,類變數

    成員變數:屬於物件,物件變數,例項變數

B:記憶體位置不同

    靜態變數:方法區的靜態區

    成員變數:堆記憶體

C:生命週期不同

    靜態變數:靜態變數是隨著類的載入而載入,隨著類的消失而消失

    成員變數:成員變數是隨著物件的建立而存在,隨著物件的消失而消失

D:呼叫不同

    靜態變數:可以通過物件名呼叫,也可以通過類名呼叫

    成員變數:只能通過物件名呼叫

--------------------------------------------------------------------------------------------------

main方法的格式詳細解釋:


/*
	main方法的格式講解:
		public static void main(String[] args) {...}
		
		public:公共的,訪問許可權是最大的。由於main方法是被jvm呼叫,所以許可權要夠大。
		static:靜態的,不需要建立物件,通過類名就可以。方便jvm的呼叫。
		void:因為我們曾經說過,方法的返回值是返回給呼叫者,而main方法是被jvm呼叫。你返回內容給jvm沒有意義。
		main:是一個常見的方法入口。我見過的語言都是以main作為入口。
		String[] args:這是一個字串陣列。值去哪裡了?
			這個東西到底有什麼用啊?怎麼給值啊?
				這個東西早期是為了接收鍵盤錄入的資料的,現在不用了。
				格式是:
					java MainDemo hello world java
				JDK5後用 Scanner s = new Scanner(System.in); 
*/
class MainDemo {
	public static void main(String[] args) {
		//System.out.println(args);        //[Ljava.lang.String;@175078b
		//System.out.println(args.length); //0
		//System.out.println(args[0]);     //ArrayIndexOutOfBoundsException 陣列越界
		
		//接收資料後
		System.out.println(args); 
		System.out.println(args.length); 
		//System.out.println(args[0]); 
		for(int x=0; x<args.length; x++) {
			System.out.println(args[x]);
		}
		
		Scan
	}
}

工具類中使用靜態:


/*
	我想要對陣列進行操作
	
	在同一個資料夾下,類定義在兩個檔案中和定義在一個檔案中其實一樣的。
*/
class ArrayDemo {
	public static void main(String[] args) {
		//定義陣列
		int[] arr = {28,55,37,46,19};
		
		//需求:遍歷陣列
		/*
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
		*/
		
		//如果我有多個陣列都要進行遍歷,那麼,程式碼的重複度就很高
		//如何改進呢?用方法改進
		//呼叫
		//靜態方法
		//printArray(arr);
		
		//非靜態方法
		//ArrayDemo ad = new ArrayDemo();
		//ad.printArray(arr);
		
		//測試類的作用:建立其他類的物件,呼叫其他類的功能。
		//而我們現在的操作是跟陣列相關的,所以,你應該把這些操作定義到陣列操作類中
		//定義一個陣列的操作類
		//有了陣列操作類之後的呼叫
		//ArrayTool at = new ArrayTool();
		//at.printArray(arr);
		
		//方法改進為靜態後,就可以直接通過類名呼叫
		ArrayTool.printArray(arr);
	}
	
	/*
	public static void printArray(int[] arr) {
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	*/
	
	//假設該方法不是靜態的
	/*
	public void printArray(int[] arr) {
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	*/
}


class ArrayTool {
	
	//把構造方法私有,外界就不能在建立物件了
	private ArrayTool(){}

	public static void printArray(int[] arr) {
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]);
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	
}

工具類的完善:


/*
	我想要對陣列進行操作
	
	如何製作一個說明書呢?
		A:寫一個工具類
		B:對這個類加入文件註釋
			怎麼加呢?
			加些什麼東西呢?
		C:用工具解析文件註釋
			javadoc工具
		D:格式
			javadoc -d 目錄 -author -version ArrayTool.java
			
			目錄:就可以寫一個資料夾的路徑
			
	製作幫助文件出錯:
		找不到可以文件化的公共或受保護的類:告訴我們類的許可權不夠
*/
class ArrayDemo {
	public static void main(String[] args) {
		//定義陣列
		int[] arr = {28,55,37,46,19};
		
		//遍歷
		ArrayTool.printArray(arr);

		//獲取最值
		int max = ArrayTool.getMax(arr);
		System.out.println("max:"+max);
		
		//獲取55的索引值
		int index = ArrayTool.getIndex(arr,55);
		System.out.println("index:"+index);
	}
}


/**
* 這是針對陣列進行操作的工具類
* @author ZHOU_VIP
* @version V.10
*/
public class ArrayTool {
	
	//把構造方法私有,外界就不能在建立物件了
	/**
	* 這是私有構造
	*/
	private ArrayTool(){}

	/**
	* 這是遍歷陣列的方法,遍歷後的格式是:[元素1, 元素2, 元素3, ...]
	* @param arr 這是要被遍歷的陣列
	*/
	public static void printArray(int[] arr) {
		System.out.print("[");
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) {
				System.out.println(arr[x]+"]");
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
	
	/**
	* 這是獲取陣列中最大值的方法
	* @param  arr 這是要獲取最大值的陣列
	* @return 返回陣列中的最大值
	*/
	public static int getMax(int[] arr) {
		int max = arr[0];
		
		for(int x=1; x<arr.length; x++) {
			if(arr[x] > max) {
				max = arr[x];
			}
		}
		
		return max;
	}
	
	/**
	* 獲取指定元素在陣列中第一次出現的索引,如果元素不存在,就返回-1
	* @param arr 被查詢的陣列 
	* @param value 要查詢的元素
	* @return 返回元素在陣列中的索引,如果不存在,返回-1
	*/
	public static int getIndex(int[] arr,int value) {
		int index = -1;
		
		for(int x=0; x<arr.length; x++) {
			if(arr[x] == value) {
				index = x;
				break;
			}
		}
		
		return index;
	}
}


相關文章