1 / 25

Ch07 巢狀類別

Ch07 巢狀類別. 物件導向程式設計 (2). 巢狀類別 - 說明. 在 Java 類別之中可以擁有其它類別的成員,這種類別稱為「巢狀類別」( Nested Classes )。 巢狀類別強調類別之間的關係,成員類別稱為「內層類別」( Inner Classes )。 例如: Employee 巢狀類別擁有成員類別 Phone 的內層類別, Employee 是巢狀類別的「外層類別」( Enclosing Class )。. 巢狀類別 - 圖例. Employee 物件的圖例,如下圖所示:. 巢狀類別 - 範例.

kobe
Download Presentation

Ch07 巢狀類別

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Ch07 巢狀類別 物件導向程式設計(2)

  2. 巢狀類別-說明 • 在Java類別之中可以擁有其它類別的成員,這種類別稱為「巢狀類別」(Nested Classes)。 • 巢狀類別強調類別之間的關係,成員類別稱為「內層類別」(Inner Classes)。 • 例如:Employee巢狀類別擁有成員類別Phone的內層類別,Employee是巢狀類別的「外層類別」(Enclosing Class)。

  3. 巢狀類別-圖例 • Employee物件的圖例,如下圖所示:

  4. 巢狀類別-範例 class Employee // Employee外層類別 { ………… class Phone // Phone內層類別 { …………… } ………… }

  5. 巢狀類別-特點 • 巢狀類別強調類別間的關係,例如:員工擁有連絡電話的資料,所以Phone類別屬於Employee類別的一部分。 • 巢狀類別的內層類別也屬於外層類別的成員,所以其它成員可以存取或呼叫內層類別的成員變數和方法,就算是宣告成private的都一樣可以存取,反之內層類別的方法也可以直接存取其它成員變數和呼叫成員方法。 • 在Java程式檔案只允許一個宣告成public的類別,如果巢狀類別宣告成public,內層類別也能夠擁有public的存取權限。

  6. class Ch06_03 { public static void main(String [] args) { Employee0603 e1 = new Employee0603("ToTo", "07-111-1111", "0911-111-111"); System.out.println("呼叫物件方法printEmployee"); e1.printEmployee(); System.out.println("呼叫e1物件中的list物件的方法printPhone"); e1.list.printPhone(); System.out.println("呼叫e1物件中的list物件的屬性home和cell"); System.out.println("電話(住家): " + e1.list.home); System.out.println("行動電話: " + e1.list.cell); } } class Employee0603 { String name; Phone0603 list; Employee0603(String name, String home, String cell) { this.name = name; list = new Phone0603(home, cell); } void printEmployee() { System.out.println("在Employee類別內"); System.out.println("===== 員工 ====="); System.out.println("姓名: " + name); System.out.println("利用呼叫內部物件的屬性來取得電話 ==>"); System.out.println("電話(住家): " + list.home); System.out.println("行動電話: " + list.cell); System.out.println("利用呼叫內部物件的方法printPhone來取得電話 ==>"); list.printPhone(); } String getName() { return name; } class Phone0603 { String home; String cell; public Phone0603(String phone1, String phone2) { home = phone1; cell = phone2; } void printPhone() { System.out.println("利用呼叫外部的物件方法==>"); System.out.println("姓名: " + getName()); System.out.println("電話(住家): " + home); System.out.println("行動電話: " + cell); } } } 範例1

  7. 內層類別的使用-範例(1/2) • 例如:Customer巢狀類別,如下所示: class Customer // Customer外層類別 { ……… class Address // Address內層類別 { ……… }

  8. 內層類別的使用-範例(2/2) • 在Java程式需要先建立Customer物件,才能建立Address物件,如下所示: Customer c1 = new Customer(“ToTo", 29001234); Customer.Address home = joe.new Address(); • 上述程式碼先使用new運算子建立joe參考的Customer物件,接著使用Customer.Address宣告物件變數home,然後使用joe.new建立Address物件,最後指定成員變數值,如下所示: home.address = "台北縣五股鄉成泰路一段"; home.zip = 248;

  9. class Ch06_04 { public static void main(String [] args) { Employee0604 e1 = new Employee0604("ToTo"); Employee0604.Phone0604 p1 = e1.new Phone0604("07-111-1111", "0911-111-111"); System.out.println("呼叫物件方法printEmployee"); e1.printEmployee(); System.out.println("呼叫p1物件中的方法printPhone"); p1.printPhone(); System.out.println("呼叫p1物件中的屬性home和cell"); System.out.println("電話(住家): " + p1.home); System.out.println("行動電話: " + p1.cell); } } class Employee0604 { String name; Employee0604(String name) { this.name = name; } void printEmployee() { System.out.println("在Employee類別內"); System.out.println("===== 員工 ====="); System.out.println("姓名: " + name); } String getName() { return name; } class Phone0604 { String home; String cell; Phone0604(String phone1, String phone2) { home = phone1; cell = phone2; } void printPhone() { System.out.println("利用呼叫外部的物件方法==>"); //System.out.println("姓名: " + getName()); System.out.println("電話(住家): " + home); System.out.println("行動電話: " + cell); } } } 範例2

  10. 巢狀類別(內部類別) • 位於另一個類別之內的類別稱之為內部類別(inner classes),或稱為巢狀類別(nested classes) • 靜態內部類別 • 非靜態內部類別 • 區域內部類別

  11. 靜態內部類別 • 使用static修飾字宣告的內部類別,稱為靜態內部類別(static inner classes)。 • 靜態內部類別和類別內其它靜態成員一樣,都屬類別所有,所以類別方法可以直接使用靜態內部類別建立物件。 • 若某個類別欲使用另一個類別的靜態內部類別時,必須以點運算子(dot operator)指明靜態內部類別所屬的類別,才可使用

  12. 內層類別的使用-說明 • 巢狀類別的內層類別屬於外層類別的成員物件,所以不能宣告成static(???)的類別變數和方法,而且只有外層類別的物件存在時,內層類別才會存在。

  13. class Ch06_05 { public static void main(String [] args) { Employee0605 e1 = new Employee0605("ToTo", "07-111-1111", "0911-111-111"); System.out.println("呼叫物件方法printEmployee"); e1.printEmployee(); System.out.println("呼叫e1物件中的list物件的方法printPhone"); e1.list.printPhone(); System.out.println("呼叫e1物件中的list物件的屬性home和cell"); System.out.println("電話(住家): " + e1.list.home); System.out.println("行動電話: " + e1.list.cell); } } class Employee0605 { String name; Phone0605 list; Employee0605(String name, String home, String cell) { this.name = name; list = new Phone0605(home, cell); } void printEmployee() { System.out.println("在Employee類別內"); System.out.println("===== 員工 ====="); System.out.println("姓名: " + name); System.out.println("利用呼叫內部物件的屬性來取得電話 ==>"); System.out.println("電話(住家): " + list.home); System.out.println("行動電話: " + list.cell); System.out.println("利用呼叫內部物件的方法printPhone來取得電話 ==>"); list.printPhone(); } String getName() { return name; } static class Phone0605 { String home; String cell; public Phone0605(String phone1, String phone2) { home = phone1; cell = phone2; } void printPhone() { System.out.println("利用呼叫外部的物件方法==>"); //System.out.println("姓名: " + getName()); System.out.println("電話(住家): " + home); System.out.println("行動電話: " + cell); } } } 範例3

  14. class Ch06_06 { public static void main(String [] args) { Employee0606 e1 = new Employee0606("ToTo"); Employee0606.Phone0606 p1 = new Employee0606.Phone0606("07-111-1111", "0911-111-111"); System.out.println("呼叫物件方法printEmployee"); e1.printEmployee(); System.out.println("呼叫p1物件中的方法printPhone"); p1.printPhone(); System.out.println("呼叫p1物件中的屬性home和cell"); System.out.println("電話(住家): " + p1.home); System.out.println("行動電話: " + p1.cell); } } class Employee0606 { String name; Employee0606(String name) { this.name = name; } void printEmployee() { System.out.println("在Employee類別內"); System.out.println("===== 員工 ====="); System.out.println("姓名: " + name); } String getName() { return name; } static class Phone0606 { String home; String cell; Phone0606(String phone1, String phone2) { home = phone1; cell = phone2; } void printPhone() { System.out.println("利用呼叫外部的物件方法==>"); //System.out.println("姓名: " + getName()); System.out.println("電話(住家): " + home); System.out.println("行動電話: " + cell); } } } 範例4

  15. 非靜態內部類別 • 沒有static修飾的內部類別稱為非靜態內部類別(non-static inner classes)。 • 非靜態內部類別和其它物件成員一樣,都必須建立物件才能使用。 • 以非靜態內部類別所建立的實體,實際上都必須與外部類別的實體結合在一起。因為沒有外部類別所建立的實體,就沒有非靜態內部類別的建構子

  16. 區域內部類別 • 定義於方法內的類別,稱為區域內部類別(local inner classes)。 • 區域內部類別不屬於外部類別的類別成員,也不是物件成員,其性質就像區域變數一樣,只能在定義的方法內使用,而且必須先定義才能使用。 • 區域內部類別不使用public、protected、private和static等修飾字。 • 區域內部類別可以取用外部方法中以final宣告的變數,不是以final宣告的變數不能取用

  17. 修飾字(1/3) • 存取權限修飾字

  18. 修飾字(2/3) • 被修飾者可用的存取權限修飾字

  19. 修飾字(3/3) • 被修飾者可用的修飾字

  20. 類屬(is a) 和擁有(has a) class A extends B implements C, D { E e; F f; A(){ e = new E(); f = new F(); } } • 類屬(is a)關係為物件和類別(或介面)之間的關係。A型別的物件可以類屬於類別A、類別B、介面C和介面D。 • 擁有(has a)關係為物件和物件之間的關係。A型別的物件擁有E型別的物件及F型別的物件。

  21. 內部類別與繼承 父類別包含內部類別時,子類別也可以繼承內部類別,如同繼承其它成員一樣。 內部類別可以有繼承關係,而且沒有特別限制。

  22. 範例5:內部類別繼承其它類別 • class EX8_23 • { //靜態內部類別,繼承Super23 • static class Sub1 extends Super23 {} • //一般內部類別,繼承Super23 • class Sub2 extends Super23 {} • public static void main(String [] args) • { System.out.println( new EX8_23.Sub1() ); • System.out.println( new EX8_23().new Sub2() ); • //區域類別,繼承Super23 • class Sub3 extends Super23 {} • System.out.println( new Sub3() ); } } • //Super23類別定義 • class Super23 • { Super23() • { System.out.print("Super23建構子被呼叫了\t"); } }

  23. 匿名類別 匿名類別(Anonymous classes)是區域內部類別的一種,顧名思義匿名類別沒有名稱,所以也不能定義建構子。 匿名類別的目的只是要建立一個物件,物件建立之後就不會再使用該類別。 匿名類別常當作覆蓋或實作抽象方法之用。

  24. 匿名類別 匿名類別的功能就是只建立一個物件,所以類別主體的定義和建立物件是一氣呵成的。 繼承類別建立匿名類別: new 父類別(參數列) { // 類別主體 } 實作介面建立匿名類別: new 介面() { // 類別主體 }

  25. 範例6:匿名類別 • class EX8_25 • { public static void main(String [] args) • { Sup s = new Sup() • { //實體初始化區塊 • { System.out.println(this); } • void m() //覆蓋方法 • { System.out.println(“覆蓋過的m方法”); } • void n() //匿名類別自訂的方法 • { System.out.println(“自訂的n方法”); } • }; • s.m(); • //s.n(); //錯誤 • } • } • //Sup類別定義 • class Sup • { void m() • { System.out.println("Sup實體的m方法"); • } • }

More Related