1. 程式人生 > 實用技巧 >Java基礎之:OOP——類變數與類方法

Java基礎之:OOP——類變數與類方法

Java基礎之:OOP——類變數與類方法

類變數與類方法,我們習慣也將其稱為靜態變數與靜態方法。

類變數/靜態變數

通過一個實際案例來了解,為什麼需要使用靜態變數。

引入案例

宣告一個學生類,每建立一個學生物件,統計學生的人數。

public class Test{
    public static void main(String[] args){
        
        int count = 0; //區域性變數,累積計數
        Student stu1 = new Student("小范");
        count ++;
        Student stu2 = new Student("小黃");
        count ++;
        Student stu3 = new Student("小雨");
        count ++;
        
        System.out.println("目前學生人數有:" + count);
    }
    
}

class Student{
    private String name;
    
    public Student(String name){
        this.name = name;
    }
    
}

通過這個案例我們可以看到,count作為一個區域性變數,獨立於Student外,當然也和建立的學生物件沒有任何關聯。以後在訪問count的時候會很麻煩,在Student類中訪問count也很麻煩。

解決方案:將count設定為類變數/靜態變數

解決案例

package static_args_methods.args;

public class Static_args {

	public static void main(String[] args) {
		Student student = new Student("小范");
		System.out.println(student.showFee());	// 100
		
		Student student2 = new Student("小黃");
		System.out.println(student2.showFee());	//200
//		System.out.println(Student.fee); //私有屬性,無法訪問
		System.out.println(Student.count); //2
		
	}
}

class Student{
	private String name;
	//static + 訪問修飾符 + 型別 + 屬性名
	static private double fee; //學費
	
	static Blackboard bb; //黑板
	
	//訪問修飾符 + static + 型別 + 屬性名 (推薦)
	public static int count; //人數
	
	public Student(String name) {
		super();
		this.name = name;
		fee += 100;	//每個學生交100學費
		count += 1;
	}
	
	public double showFee(){
		return fee;
	}
}

class Blackboard{
	
}

案例說明

由此案例,引出類變數/靜態變數的概念及使用。

概念

類變數也叫靜態變數/靜態屬性,是該類的所有物件共享的變數,任何一個該類的物件去訪問它時,取到的都是相同的值,同樣任何一個該類的物件去修改它時,修改的也是同一個變數。

定義語法

訪問修飾符 static 資料型別 變數名; [推薦]

static 訪問修飾符 資料型別 變數名;

訪問方法

類名.類變數名 [推薦]

或者 物件名.類變數名 【靜態變數的訪問修飾符的訪問許可權和範圍 和 普通屬性是一樣的。】

使用說明

  1. 當需要一個類的所有物件都可以共用一個屬性時,就可以將此屬性設定為靜態屬性。例如,Student中的count屬性。

  2. 被靜態static修飾過的屬性,在類載入時就會被生成,然後初始化。

  3. 建議使用“類名.屬性名” 的方式訪問靜態屬性,因為靜態屬性(類變數)的生命週期是隨類的載入開始,隨著類消亡而銷燬。在類載入的時候,並沒有物件被建立,此時也可以使用類變數。

  4. 類變數是所有物件共享使用的,而普通變數是每個物件都獨有的。

  5. 類變數的使用,訪問許可權也是由訪問修飾符修飾的。例如:Student 的類變數 count 是 private 修飾的,那麼在 Static_args 類中也不能通過 Student.count 來訪問。

類方法/靜態方法

類方法也叫靜態方法 。

形式如下:

訪問修飾符 static 資料返回型別 方法名() { } 【推薦】

static 訪問修飾符 資料返回型別 方法名() { }

類方法的呼叫:

使用方式: 類名.類方法名 或者 物件名.類方法名 【前提是 滿足訪問修飾符的訪問許可權和範圍】

使用說明

  1. 類方法與普通方法都是在類載入時就載入了,將其結構資訊放在方法區中。

  2. 類方法中沒有this關鍵字,也不能使用super關鍵字。因為類方法在類載入時就可以呼叫,此時還沒有物件被生成。而this與super都是代表物件的關鍵字。

  3. 類方法/靜態方法 只能訪問靜態屬性或者呼叫其他靜態方法,不可以使用成員屬性與成員方法。因為在類方法被載入時,成員屬性與成員方法都還沒有被加載出來,不能使用。【前提是 滿足訪問修飾符的訪問許可權和範圍】

  4. 而在成員方法(普通方法)中可以使用所有的靜態方法與靜態屬性。【前提是 滿足訪問修飾符的訪問許可權和範圍】

  5. 但不要誤理解為,靜態方法中使用的任何屬性或方法都必須是靜態的。也可以在靜態方法中宣告普通屬性來使用。

說明案例

public class StaticMethodDetail {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//類方法可以通過類名呼叫,也可以通過物件名呼叫
		new DD().hi();
		DD.hi();
	}

}


class EE {
	public String name = "EE";
}

class DD extends EE {
	/*
	 * 類方法和普通方法都是隨著類的載入而載入,將結構資訊儲存在方法區 :類方法中無this的引數,普通方法中隱含著this的引數
	 * 類方法中,不能使用this ,普通方法可以使用this

	 */
	
	private int num = 200;
	private static String name = "老王";
	public static void hi() {
		//System.out.println(this.num);
	}
	
	//類方法中不允許使用和物件有關的關鍵字,比如this和super
	public static void ok() {
		//System.out.println(this.num);
		//System.out.println(super.name);
	}
	//類方法(靜態方法)中 只能訪問 靜態變數 或靜態方法
	
	public void m1() { 
		
	}
	
	public static void hello() {
		ok();
		//m1();
		System.out.println(name);
	}
	//普通成員方法(非靜態方法),既可以訪問 普通變數(方法),也可以訪問靜態變數(方法)
	public void m2() {
		ok();
		m1();
		System.out.println(name);
		System.out.println(num);
	}
}

 

簡單案例

package static_args_methods.methods;

public class Static_methods {

	public static void main(String[] args) {
		Person person = new Person("小黃", 2000);
		Person person2 = new Person("小范", 2500);
		
		//可以使用類名呼叫,也可以使用物件呼叫
		System.out.println(Person.show());	//建議
		System.out.println(person2.show());	
	}

}

class Person{
	private String name;
	private double salary; //工資
	private static double totalSalary; //總工資
	
	public Person(String name, double salary) {
		super();
		this.name = name;
		this.salary = salary;
		sumSalary(salary);
	}
	
	//靜態方法
	public static void sumSalary(double salary) {
		totalSalary += salary;
	}
	
	//返回總工資(靜態方法裡只能使用靜態屬性與方法)
	public static double show() {
//		salary = 100; //Cannot make a static reference to the non-static field salary
//		this.totalSalary = 100; //在靜態方法中沒有this指標,也不可以使用super
		return Person.totalSalary;
	}
}

 

理解main

由於java虛擬機器需要呼叫類的main()方法,所以該方法的訪問許可權必須是public,又因為java虛擬機器在執行main()方法時不必建立物件,所以該方法必須是static的,該方法接收一個String型別的陣列引數,該陣列中儲存執行java命令時傳遞給所執行的類的引數。

簡單案例

public class TestMain
{

	private String name = "jack";
	private static int num = 600;

	//1.main方法時JVM呼叫,因此 public static
	//2. String[] args 是執行程式時,可以輸入的
	//3. 比如 java TestMain tom jack smith
	public static void main(String[] args) {
		
		for(int i= 0 ;  i < args.length;i++) {
			System.out.println(args[i]);
		}

		//m1();
		m2();
		System.out.println(num);

		//如果我們就是要再 main呼叫非靜態的成員,需要先建立物件,再呼叫..
		TestMain tm = new TestMain();
		tm.m1();
	}

	public void m1() {
		
	}

	public static void m2() {
		
	}
}