[Java] 15.1. 內隱類別

內隱類別,類別中的類別,在Java中非常重要。

 

image/svg+xml15.1. 內隱類別 – Inner Class class Person { String id; String name; String gender; int age; } class Company { String name; class Employee extends Person { String employeeID ; int salary ; } } class Main{ public static void main( String [] args){ Company com = new Company (); com.name = "Java 股份有限公司 " ; Company.Employee emp = com.new Employee (); emp.id = "k12345678" ; emp.name = "Jack" ; emp.gender = " " ; emp.age = 20 ; emp.employeeID = "048679" ; emp.salary = 40000 ; } } class Main{ public static void main( String [] args){ Employee emp; emp = new Employee (); } } 執⾏結果 Main.java:4: error: cannot find symbol Employee emp; ^ symbol: class Employee location: class Main Main.java:6: error: cannot find symbol emp = new Employee(); ^ symbol: class Employee location: class Main 2 errors class Company { String name; class Employee extends Person{ String employeeID; int salary; } Employee createEmployee (){ return new Employee (); } } class Main{ public static void main( String [] args){ Company com = new Company (); com.name = "Java 股份有限公司 " ; Company.Employee emp = com.createEmployee (); emp.id = "k12345678" ; emp.name = "Jack" ; emp.gender = " " ; emp.age = 20 ; emp.employeeID = "048679" ; emp.salary = 40000 ; } } class Product { String name; int price ; } class Company { String name; private int cash = 10000 ; Employee createEmployee(){ return new Employee(); } class Employee extends Person{ String employeeID; int salary; void buy ( Product p){ cash = cash - p.price; System.out.println( " ⽬前公司的現⾦為 " + cash ); } } } class Main{ public static void main( String [] args){ Company com = new Company (); com.name = "Java 股份有限公司 " ; Company . Employee emp = com.createEmployee (); Product p1 = new Product (); p1.name= " 可⼝可樂 " ; p1.price= 20 ; Product p2 = new Product (); p2.name= " ⼝香糖 " ; p2.price= 50 ; emp.buy ( p1 ); emp.buy ( p2 ); } } 執⾏結果 ⽬前公司的現⾦為 9980 ⽬前公司的現⾦為 9930 class Company { String name; private int cash= 10000 ; Employee createEmployee(){ return new Employee(); } class Employee extends Person{ String employeeID; int salary; void buy( Product p){ cash = cash - p.price; System.out.println( " ⽬前公司的現⾦為 " + cash); } void introduceCompany (){ System.out.println( " 員⼯ " + this . name + ⼯作於 " ); System.out.println( Company. this . name ); System.out.println( " 零⽤⾦還有 " + Company. this . cash ); } } } J15_1_1 Person.java 如何表⽰ 先有公司 J15_1_1 Company.java 才有員⼯的概念 ? 1. 簡單的⼈員類別( Person )。 2. 員⼯類別( Employee )被放在公司類別 Company )中了,這時候⼈員類別就是成為 內隱類 。當然,公司類別此時就是員⼯類別的 外部類別 3. 雖然是內隱類別,但還是可以繼承其他類別的。 就像員⼯內隱類別繼承了非內隱類別的⼈員類別。 4. 內隱類別也是類別,因此可以擁有類別可以擁有的建構式、 屬性、⽅法。(稍後我們會為⼈員類別加上⽅法)。 內隱類別在編譯後的類別檔檔名將以 外部類別 $ 內隱類別 .class” 的⽅式呈 現。如本範例,員⼯類別( Employee )的類別檔檔名為 “Company$Employee.class” J15_1_1 Main.java 1. 先建立⼀個公司物件( Company )。 4. 員⼯類別的型別這時並不像變數的型別需要在前⾯加上外部類別 - 公司類 別的型別。只要直接寫到內部類別的名稱就可以了,原因很簡單,因為前⾯ com 變數的公司物件,以經說明了等會建立的物件⼀定是內隱類別的物件。 2. 變數的型別以巢狀的⽅式呈現。型別名稱為 [ 外部類 ].[ 內隱類別 ] ,以表⽰某個類別下的內隱類別。 3. 建立員⼯內隱類別( Employee )還是需要使⽤到 new 關鍵字,但是 new 關鍵字前⾯必須是外部類別 - 公司類別( Company )的物件,然後以 逗點( . )的⽅式連結 new 關鍵字。以創造公司物件下專屬的員⼯物件。 J15_1_2 Main.java 1. 這裡會發⽣第 1 個編譯錯誤,因為員⼯類別( Employee )是定義在公司類別中的 Company ),並不能只寫到員⼯類別作為變數的型別(當然包括參數的型別)。 2. 這裡會發⽣第 2 個編譯錯誤,這也是因為員⼯是定義在公司 類別中的,因此並不能直接建立獨立的員⼯類別。 3. 根本沒有叫作 Employee 的類別,因此無法宣告變數。 4. 因為找不到⼀個叫作 Employee 的類別,所以無法建立員⼯物件。 J15_1_3 Main.java 1. 這是公司類別( Company ),其中有個內隱類別-員⼯類別( Employee )。 2. 在公司類別中可以只以 “Employee” 作為型別,並不⽤寫 ”Company.Employee” 。原因是員⼯類別是宣告在公司類 別中的,因此公司類別可以知道什麼是員⼯類別。 3. 同理,定義在公司類別中的建立員⼯物件的動作,是可以只寫到 “Employee” 即可 直接建立。當然,這個建立的員⼯物件的型別其實是 “Company.Employee” J15_1_3 Main.java 1. 建立公司物件( Company )。 2. 變數的型別還是要以 “Company.Employee” 來表⽰,因為此變數並 不是在公司類別中出現的,因此還是要完整的員⼯類別的型別名稱。 3. 公司物件可以使⽤建立員⼯⽅法( createEmployee )建立員⼯物 件,但記得這個員⼯物件的完整型別還是 “Company.Employee” J15_1_4 Product.java J15_1_4 Company.java J15_1_4 Main.java 1. 這是新的產品類別( Product ),等會⽤來表⽰員⼯要買 的東⻄。當然每個東⻄都會有價格( price )的。 2. 這是公司類別( Company )。 3. 公司類別的零⽤⾦( cash ),它是被私有化的屬性。 5. 員⼯的購買⽅法( buy() )是可以直接使⽤公司類別的所有成員的, 即使是私有化的也是⼀樣,就像是零⽤⾦屬性( cash ),即使被私有化 了,還是可以直接使⽤。因為員⼯類別也是公司類別的成員之⼀。 4. 這是內隱類別-員⼯類別( Employee )。 6. 建立公司物件( Company )。 7. 透過公司物件的建立員⼯⽅法( createEmployee() )建立員⼯物件( Employee )。 8. 兩樣要買的產品( Product ),分別是 20 50 元。 9. 在購買⽅法( buy() )中,會使⽤公司的零⽤⾦( cash )來⽀付購 買產品的⽀出,雖然公司類別的零⽤⾦屬性是私有化的( private ), 但因員⼯類別是公司的內隱類別,因此也是屬於公司的成員,因此成員 與成員之間的相互存取是不再受私有化限制的。 J15_1_5 Company.java 1. 這是公司類別( Company )。 2. 這是內隱類別-員⼯類別( Employee )。 3. 員⼯的公司介紹⽅法( IntroduceCompany() ), 以介紹⽬前公司的相關資訊。 4. 這是員⼯繼承⾃⼈員的姓名屬性 name ),可透過 this 的⽅式存取。 5. 使⽤ ”Company.this” ⽅式取得的物件,將會是外部類別 Company 的實體物件,因此這裡的 name 屬性將會是公司的名稱屬性。 這樣就解決定員⼯類別的 name 被遮蓋住公司類別的 name 的問題。 6. 這也是使⽤ ”Company.this” ⽅式取得公司 物件,然後存取零⽤⾦屬性( cash )的例⼦。 沒有公司就沒有員⼯的理念, 在物件導向上要如何表⽰? 內隱類別的技巧, 讓員⼯類別成為公司類別中的⼀部份 透過 公司物件 .new” 關鍵字建立員⼯物件 注意,只有公司物件可以建立員⼯物件 1 2 1 2 在公司物件內直接使⽤ new 關鍵字建立員⼯物件 測試⼀下 createEmployee() ⽅法 員⼯是公司的成員, 因此可以直接存取公司的所有資源 1 2 1 2 “Company.this” 幫您取得公司類別的實體物件

留言