Java入門系列-14-深入類和物件

要成為王的男人發表於2018-10-29

這篇文章用大量的程式碼幫你搞懂:值傳遞和引用傳遞、構造方法、方法過載、static關鍵字的使用

方法引數傳遞-值傳遞和引用傳遞

1.值傳遞

敲一敲:

/**
 * 使用方法交換兩個變數的值
 * @author Jack
 *
 */
public class Swap {
	public static void main(String[] args) {
		int a=10;
		int b=8;
		Swap swap=new Swap();
		swap.swap(a, b);
		System.out.println("呼叫方法後:a="+a+",b="+b);
	}
	public void swap(int a,int b) {
		int temp=a;
		a=b;
		b=temp;
		System.out.println("交換後:a="+a+",b="+b);
	}
}
複製程式碼

在上面這段程式碼中我們發現在方法內部對這兩個引數進行交換成功,但是在呼叫方法後外部變數並沒有任何變化。引數的型別為值型別,使用值型別作為引數稱為值傳遞。

值傳遞方法內部修改外部不保留,引數內的變數是實參的副本。

2.引用傳遞

敲一敲:

import java.util.Arrays;
public class Swap2 {
	public static void main(String[] args) {
		int[] ages= {1,2,3};
		Swap2 swap=new Swap2();
		System.out.println("呼叫change前:"+Arrays.toString(ages));
		swap.change(ages);
		System.out.println("呼叫change後:"+Arrays.toString(ages));
	}
	public void change(int[] ages) {
		ages[0]=100;
	}
}
複製程式碼

在方法內部對引數變數進行修改後,方法的外部列印後也進行了修改,陣列、類都是引用型別,使用引用型別作為引數傳參被稱為引用傳遞。

引用傳遞方法內部修改外部保留,引數內的變數是對實參的引用。

構造方法

在建立物件的時候,我們使用過這樣的程式碼 類名 物件名=new 類名(); ,其實這時就是在呼叫此類的構造方法 public 類名(){}

構造方法又稱建構函式,是類中一種特殊的方法。構造方法名與類名相同,不返回任何值,主要完成物件的初始工作。

語法:

訪問修飾符 構造方法(可以指定引數){
    //初始化程式碼
}
複製程式碼

敲一敲:無參構造方法

public class Student {
	String name;
	int age;
	public Student() {
		name="張三";
		age=18;
	}
	public static void main(String[] args) {
		Student stu=new Student();
		System.out.println(stu.name);
		System.out.println(stu.age);
	}
}
複製程式碼

這樣就能在 new 時給物件的屬性初始化值,但是在每一次 new 的時候都是相同的值。能不能在 new 的同時指定值呢?那就是使用有參的構造方法。

敲一敲:有參構造方法

public class Student {
	String name;
	int age;
	public Student(String name,int age) {
		this.name=name;
		this.age=age;
	}
	public static void main(String[] args) {
		Student stu=new Student("張三",12);
		System.out.println(stu.name);
		System.out.println(stu.age);
	}
}
複製程式碼

this 代表當前物件的引用,在有參構造方法中使用時區分屬性和引數

上面的這段程式碼,能不能這樣建立物件 Student stu=new Student();

答案是不可以的

不顯式編寫構造方法,系統將預設提供無參構造方法
一旦提供編寫構造方法,系統便不再提供無參構造方法

所以這時我們可以同時編寫有參構造方法和無參構造方法,使我們建立物件的時候更加的靈活。

敲一敲:同時提供有參和無參構造方法

public class Student {
	String name;
	int age;
	//無參構造方法
	public Student() {}
	//有參構造方法
	public Student(String name,int age) {
		this.name=name;
		this.age=age;
	}
	public static void main(String[] args) {
		//使用有參構造方法
		Student stu1=new Student("張三",12);
		System.out.println(stu1.name);
		System.out.println(stu1.age);
		//使用無參構造方法
		Student stu2=new Student();
		stu2.name="李四";
	}
}
複製程式碼

方法過載

在上一部分中,我們使用了有參和無參的方法,為什麼在一個類中可以定義多個類名相同的方法呢?因為實現了方法過載。只不過構造方法過載是一種特殊的過載。

過載的條件(兩同兩不同)

在同一個類中,方法名相同,引數型別不同,引數個數不同

敲一敲:實現普通方法的過載

public class Teacher {
	public void teach(String project) {
		System.out.println("教授科目:"+project);
	}
	public void teach(String project1,String project2) {
		System.out.println("教授科目:"+project1+" 和 "+project2);
	}
	public static void main(String[] args) {
		Teacher t=new Teacher();
		t.teach("語文");
		t.teach("語文","數學");
	}
}
複製程式碼

在生活中有很多活動就屬於過載,比如 表演 ,給表演者劇本就是在表演戲劇,給表演者樂器,就是表演演奏,給表演者話筒,就是表演相聲。

在程式碼中使用過載也有很多好處,比如 System.out.println(); 這個方法也有很多過載形式,可以傳入 int string object 作為引數,減少了書寫和記憶的成本。你肯定不希望列印每種資料型別時都單獨定義一個方法,像後面這樣 printIntln(int out) printDoubleln(double out) printLongln(long out) ……

this 關鍵字的用法

在使用建構函式時使用了 this 關鍵字用於區分屬性和引數,那只是第一種用法,除此之外還可以呼叫方法、呼叫構造方法。

呼叫屬性:this.health=100;

呼叫方法:this.print();

呼叫構造方法:this(); this("張三",18); 必須用在構造方法中的第一行

static 關鍵字的用法

如何通過類名直接訪問類中的成員,像之前用過的 Arrays.toString(),檢視原始碼部分程式碼如下。

public static String toString(int[] a) {
    if (a == null)
        return "null";
    int iMax = a.length - 1;
    if (iMax == -1)
        return "[]";

    StringBuilder b = new StringBuilder();
    b.append('[');
    for (int i = 0; ; i++) {
        b.append(a[i]);
        if (i == iMax)
            return b.append(']').toString();
        b.append(", ");
    }
}
複製程式碼

當前這個方法使用了 static 關鍵字進行了修飾

還可以修飾成員變數:

public class Teacher {
	static final String SEX_MALE="男";
	static final String SEX_FEMALE="女";
	String sex;
	public static void main(String[] args) {
		Teacher teacher=new Teacher();
		teacher.sex=Teacher.SEX_FEMALE;
		System.out.println(teacher.sex);
	}
}
複製程式碼

final 修飾後的變數都將變成常量
常量的值不能修改,只能使用

可以修飾程式碼塊:

public class Teacher {
	static final String SEX_MALE="男";
	static final String SEX_FEMALE="女";
	String sex;
	//程式碼塊
	static {
		System.out.println("靜態程式碼塊");
	}
	public static void main(String[] args) {
		Teacher teacher=new Teacher();
		teacher.sex=Teacher.SEX_FEMALE;
		System.out.println(teacher.sex);
	}
}
複製程式碼

static 關鍵字使用注意事項

1.static 修飾了屬性和程式碼塊後,會先初始化靜態屬性,再執行靜態程式碼塊

public class TakeCare1 {
	static String name="aa";
	static {
		System.out.println(name);
		System.out.println("靜態程式碼塊執行");
	}
	public TakeCare1() {
		System.out.println("建構函式執行");
	}
	public static void main(String[] args) {
		TakeCare1 t=new TakeCare1();
	}
}
複製程式碼

2.static 關鍵字不能修飾區域性變數

public class TakeCare2 {
	public static void main(String[] args) {
		static int a=10;
	}
}
複製程式碼

3.同一個類中的靜態方法可以互相通過方法名直接呼叫

public class TakeCare2 {
	public static void test1() {
		System.out.println("method test1");
		test2();
		TakeCare2.test2();
	}
	public static void test2() {
		System.out.println("method test2");
	}
	public static void main(String[] args) {
		test1();
	}
}
複製程式碼

4.不同類中的靜態成員呼叫需要通過 類名.成員 呼叫

public class TakeCare4 {
	public static void main(String[] args) {
		Test.test();
		System.out.println(Test.name);
		//test();//去掉前面註釋試試
	}
}
class Test{
	static String name="Test";
	public static void test() {
		System.out.println("method test");
	}
}
複製程式碼

5.同一個類中非靜態方法可以直接通過 屬性名或方法名 呼叫

public class TakeCare5 {
	static String name="static property";
	public static void st() {
		System.out.println("static method");
	}
	public void test() {
		System.out.println("instance method");
		System.out.println(name);
		st();
	}
}
複製程式碼

6.靜態方法不能直接使用例項成員,需要通過物件呼叫

public class TakeCare6 {
	public static void st() {
		System.out.println("static method");
		TakeCare6 tc=new TakeCare6();
		tc.test();
		//test();//去掉註釋後報錯 Cannot make a static reference to the non-static method test() from the type TakeCare6
	}
	public void test() {
		System.out.println("instance method");
	}
}
複製程式碼

總結:static 修飾後的成員就像萬能的 O 型血,在任何地方都能 類名.成員 呼叫(private 修飾除外),例項方法除了本類中的方法,只能 物件.成員 呼叫

搜尋關注公眾號「享智同行」,第一時間獲取技術乾貨

相關文章