標籤:類型 類構造 使用 操作 font 尋找 [] 擷取 實值型別
類:
是構造對象的模板或藍圖;
類構造對象的過程稱為建立對象的執行個體;
用Java編寫的所有代碼都位於某個類的內部;
封裝:
將執行個體域(屬性)和方法包在一起;
對對象的使用者隱藏了資料的實現方式;
關鍵在於:絕對不能讓類中的方法直接地訪問其它類的執行個體域,程式僅通過對象的方法與對象資料進行互動;即使用方法將類的資料隱藏起來,控制其他類對該類的修改和訪問資料的程度;就是說,一般擷取、修改對象的屬性都是通過方法來操作;
對於每個特定的執行個體(對象)都有一組特定的執行個體域值,這些值的集合就是這個對象的目前狀態;
優點:針對域
避免域被其他類的方法直接存取;(所以一般都定義為私人的,只通過本類中的方法進行調用和修改)
可以改變內部實現,除了該類的方法之外,不會影響其他代碼;
更改器方法可以執行錯誤檢查;
注意:
不要編寫返回引用可變對象的訪問器方法;如果需要返回一個可變對象的引用,應該首先對它進行複製;
繼承:
子類會繼承父類所有的內容(包括所有屬性和方法,但不包括構造方法),但不一定能直接使用;
java只支援單繼承,extends後面只能跟一個類;
舉例:
類B繼承類A;
類B建立的執行個體,可以調用和類A中相同的公有的方法和公有的執行個體域;但不能調用或設定類和A中相同的私人執行個體域和私人方法;
一個類的所有對象,每個對象都有自己的一份執行個體域,但所有對象共用那些方法;
繼承的特性:
1.當一個類繼承自另一個類,子類中沒有顯式定義和父類相同的方法(方法名、參數、傳回值都一樣)時。用子類的對象調用方法時,會首先在子類中尋找,如果子類中沒有該方法,再到父類中尋找。
執行個體(1):
1 public class Demo1 2 { 3 // 父類定義的 print()方法 4 public void print() 5 { 6 System.out.println(123); 7 } 8 } 9 10 11 public class Demo2 extends Demo112 {13 // 子類沒有顯式定義和父類相同的方法(方法名、參數、傳回值類型都一樣)14 }15 16 17 public class Test18 {19 public static void main(String[] args)20 {21 Demo2 demo = new Demo2();22 // 最後列印出的結果是 12323 demo.print();24 }25 }
執行個體(2):
public class Demo1{ // 父類定義的 print()方法 public void print() { System.out.println(123); }}public class Demo2 extends Demo1{ // 子類顯式定義和父類相同的方法(重寫) public void print() { System.out.println(456); }}public class Test{ public static void main(String[] args) { Demo2 demo = new Demo2(); // 最後列印出的結果是 456 demo.print(); }}
2.子類與父類之間建構函式的使用規則:
(1).Java中每個類都有一個建構函式;如果類中沒有顯式定義建構函式,則編譯器會預設提供一個無參建構函式;
(2).子類繼承父類時,必須在建構函式中調用父類的建構函式;
(3).父類沒有顯式定義建構函式,只有一個預設的無參建構函式,那麼子類繼承父類時,也是通過在預設的無參建構函式調用父類的建構函式;
public class Demo1{ /** * 這是編譯器預設提供的無參建構函式 * 這個建構函式是隱藏的,看不到,現在讓它顯式出來只是為了看到無參建構函式的樣子 * 這裡的super()調用的是 Object 類的構造方法 * 父類並沒有顯式定義建構函式 */ public Demo1() { super(); }}public class Demo2 extends Demo1{ /** * 子類繼承父類,通過編譯器提供的預設構造方法調用父類的構造方法 * 這裡構造方法也是隱藏的 * 這裡的 super() 調用的是 Demo1 類的構造方法 */ public Demo2() { super(); }}
(4). 父類顯示定義了帶參(必須是帶參)建構函式,那麼子類繼承父類時,也必須顯示定義一個帶參建構函式,在這個建構函式中調用父類的建構函式;
public class Demo1{ /** * 父類顯示定義了一個帶參建構函式 */ public Demo1(String s) { super(); System.out.println(s); }}public class Demo2 extends Demo1{ /** * 子類必須顯示定義一個帶參建構函式來調用父類的建構函式 * 這裡的 super(s) 就是調用父類的帶參建構函式,s是實參 */ public Demo2(String s) { super(s); }}
3.當一個方法只在父類中定義時,調用該方法時使用到的屬性是父類的屬性;如果該方法中又調用了其他方法,那麼還是按照之前的順序,先在子類中尋找,再在父類中尋找。
public class Demo1{ int x = 6; private int y = 2; public Demo1(int a) { x = a; } int getz() { int z; z = x / y; return z; } void show() { System.out.println("x=" + x); System.out.println("y=" + y); // 方法中調用了其它方法 System.out.println("z=" + getz()); }}public class Demo2 extends Demo1{ // 重新定義了 x,y 變數 int x = 3, y = 5, z; public Demo2(int a) { super(a); } // 重寫了 getz() 方法 int getz() { z = x + y; return z; } // 定義專屬的方法 public void print() { System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("z = " + z); } }public class Test{ public static void main(String[] args) { Demo1 demo1 = new Demo1(10); Demo2 demo2 = new Demo2(9); demo1.show(); /** * 列印出的結果: * x=9:子類 Demo2 通過構造方法將父類 Demo1 中的 x 屬性值設為9,子類對象調用的 * show() 方法在子類中沒有重新定義(重寫),調用的是繼承自父類的 show()方法, * 則在父類中的 show() 方法中調用的 x 屬性就是父類中的屬性,值為 9; * y=2:同樣的道理,子類調用的 show() 方法在子類中沒有重新定義,所以 show() 方法 * 中調用的 y 屬性是父類中的 y 屬性,值為 3; * z=8:show() 方法中的 getz() 方法在子類和父類中都有,則優先調用子類中的 getz() * 方法,那麼子類中的getz()放用到的 x,y,z 屬性就是子類中定義的 x,y,z 屬性,x,y 的 * 值分別為 3和5,所以 y 計算出來的值是 8; */ demo2.show(); /** * 調用子類特有的方法,那方法裡面用的屬性都是子類重新定義好的屬性 */ demo2.print(); }}// 最後列印出的結果:// x=10// y=2// z=5// x=9// y=2// z=8// x = 3// y = 5// z = 8
Java 物件導向