Presentation is loading. Please wait.

Presentation is loading. Please wait.

Course Introduction CLASS III. Outline “equals” and “==“, the equality problem The root of the class hierarchy Modifier Nested classes –Instance nested.

Similar presentations


Presentation on theme: "Course Introduction CLASS III. Outline “equals” and “==“, the equality problem The root of the class hierarchy Modifier Nested classes –Instance nested."— Presentation transcript:

1 Course Introduction CLASS III

2 Outline “equals” and “==“, the equality problem The root of the class hierarchy Modifier Nested classes –Instance nested class –Static nested class 1-2

3 1-3 Object equal? 比較兩個東西是否相等, JAVA 程式碼最常用到 的方法不外乎下列兩種 : – “==“ – 呼叫函式 equals() 普通的 data type 比較數值如整數,小數可利用簡 單的 ”==“ 來判斷相不相等 關於產生物件的 reference type 則採用 ”==“ 來比對 不一定正確 這是為什麼呢 – l-value, r-value

4 Review This Figure heap objRef1=0x3200 objRef3=0x3288 objRef2=0x4650 (Object instances inside) intValue=3 booleanValue=true (Reference type variables) (Primitive type variables) objRef4=0x3200 objRef1==ObjRef4?

5 相等的問題 “==“ 所比較的是 reference value 真正判定二個 ” 物件實體 ” 是否相等,必須判斷 “ 物 件當中的內容 ” –Ex: 二個學生物件,姓名,學號都一樣  應為同一人 – 透過實作 public boolean equals(Object o) 來解決 1-5

6 1-6 相等的迷思程式碼 class Student { String name; String id; public boolean equals(Object obj) { Student otherStudent = (Student) obj; if( this.name.equals(otherStudent.name) && this.id.equals(otherStudent.id) ) { return true; } else { return false; }

7 equals 這個方法 定義在 java.lang.Object 中 原本的實作是比較 reference value 是否相同 我們是去 “override” 在 java.lang.Object 中的 equals 1-7

8 萬物之源: java.lang.Object Java 的設計當中,所有的物件都是這個物件的子 類別 – 將繼承關係以樹狀結構表示時, java.lang.Object 就 是 root! http://java.sun.com/j2se/1.4.2/docs/api/j ava/lang/Object.htmlhttp://java.sun.com/j2se/1.4.2/docs/api/j ava/lang/Object.html 1-8

9 1-9 修飾字 final 修飾子 – final 修飾子可以套用於類別、資料或是方法。 – final 變數的值一旦設定之後,變數的值就不可更改。 – 使用 final 關鍵字可以避免此種情形 用在 method – 表示 method 無法繼續被 override 用在變數 – 不能改變變數所 hold 之 value » 對 primitive types 而言, “ 純量 ” 不能更改 » 對 reference type 而言,固定只能指向某個物件 用在類別 – 表示此類別將無法再被其他類別繼承

10 1-10 Final Example public class ConstantData{ public static void main(String[] args){ final int constantInteger=10; constantInteger=12; //error, can not assign!! } public class ConstantReference{ public static void main(String[] args){ final Student stuObj=new Student(“John”); stuObj.setName(“Yoshi”); //OK!! }

11 1-11 Final Example public class ConstantReference{ public static void main(String[] args){ final Student stuObj=new Student(“John”); stuObj = new student(“John”); //error!! } Student Class 某個 Instance final 限制 的對象 非 final 限制的 對象

12 1-12 Final Example 物件 生物 動物植物 牛馬羊豬狗牛馬羊豬狗 花草花草 不會再有其他類別 ( 不會在往下延伸 其他類別 ) final class Plant { }

13 1-13 修飾字 abstract 修飾子 – 若在類別加上 abstract 關鍵字,表示這個類別式抽象類 別 – abstract 修飾子只可以套用於 類別 (Class) 函式 (Method) – 宣告為 abstract 的類別,不能夠實體化 (new) 。 – 如果類別中的方法使用了 abstract 修飾子,該方法只有 名稱、參數內容和回傳型別的定義,不能有實作的部 份。 – 在類別中只要有一個成員方法使用了 abstract 修飾子, 則該類別也必須使用 abstract 修飾子。但不需要將所有 的成員方法都宣告成 abstract

14 1-14 abstract Example abstract class Specification{ static final int constantInteger=10; static final boolean OK=true; abstract void show(); void print(){ System.out.println(“….”); }

15 1-15 使用介面 (interface) 「介面 (interface) 」用來定義一套標準、規範 – 讓程式的撰寫有一定的規則可遵循 – 為物件之間的互動訂定規範 介面也可以被視為類別的一種 – 不同:介面內只可以定義常數和抽象方法。 介面可以當作類別的收集器 , 可使用 extends 於 interface , 以彌補 Java 中 Class 不允許多重繼承的性質。 介面只提供方法的定義而不實作該方法。 – 不能用 new 來產生物件,因為介面沒有建構子

16 1-16 使用介面 (interface) –interface 的基 本架構 interface base1 { void fun1(args1,args2,…); } interface base2 { void fun2(args1,args2,…); } class sub1 implements base1,base2 { public void fun1(args1,args2,…){ … } public void fun2(args1,args2,…){ … } }

17 1-17 宣告介面 介面裡只宣告屬性和方法,沒有建構子。 inteface Actions { public String name = "Some Actions"; public void canFly(); public void canRun(); } 會變 public static final interface Specification{ int constantInteger; //error, 沒有宣告初始值 public static abstract boolean OK=true; //error, 不能為 abstract 抽象 … 必為常數 public static void show(); //error, 不能為 static 靜態 … 必為抽象 } 會變 public abstract

18 1-18 實作介面 實作介面時,使用 implements 關鍵字 Java 不允許 class 同時繼承多個類別,但可以同時實作 多個介面。 當類別實作了介面後,該類別擁有介面中所有的方法和 屬性。類別必需負責實作介面中的所有方法。 – 因為介面只有抽象的方法 class Bird extends Animal implements Actions {} class Bird implements Actions, Action2, Action3 {}

19 1-19 繼承 interface( 介面 ) –Java CLASS 裡沒有多重繼承,若要用到多重繼承,必 須以 interface 為替代方案 interfaceabstract 多重繼承有無 建構函數不可以有可以有 方法實作必須全部由實作的類別實作 可將全部或部分方法交由繼承的類別 實作,或完全不給繼承的類別實作任 何方法 變數改變 變數必須給定初始值,之後使用不可更 改,相當於加上 final 關鍵字 可以更改 變數繼承有有

20 1-20 繼承宣告 extends 類別名稱 – 宣告此類別是繼承其它類別而來。 Java 只允許單一繼 承,意即,每個類別最多只有一個父類別。 implements 介面名稱, 介面名稱,… – 宣告此類別需要實作其它介面以增加此類別的特性。

21 1-21 利用介面模擬多重繼承 interface Action1 { public void canRun(); } interface Action2 { public void canFly(); } interface Action3 { public void canSwim(); } interface AllAction extends Action1, Action2, Action3 {} abstract class SuperAnimal implements AllAction{} class SuperDuck extends SuperAnimal{}

22 1-22 Error implements interface USB{ public void show(); public void print(); } Class USBMouse implements USB{ //error // 因為 implement 介面必須定義清楚 show() 跟 print() 動作 ~~ 不能是抽象的 !! } public class Application{ public static void main(String agrs){ USBMouse usbMouse = new USBMouse(); }

23 1-23 Right implements interface USB{ public void show(); public void print(); } Class USBMouse implements USB{ public void show(){ System.out.println(“I’m USB Mouse”); } public void print(){ System.out.println(“I’m moving”); }

24 1-24 建立巢狀類別 巢狀類別 (Nested Class) 指類別中還有其他的類別。 – 外部的類別稱為「外圍類別 (Enclosing Class) 」 – 內部的類別稱為「巢狀類別 (Nested Class) 」。 從外圍類別外使用內部類別: – 外部類別名稱. 內部類別名稱 依照巢狀類別的存取特性,巢狀類別分為: – 內部類別 (Inner Class) – 靜態內部類別 (Static Inner Class) – 局部內部類別 (local inner Class) – 方法類別 (Method local Class) – 匿名類別 (Anonymous Class)

25 1-25 內部類別 (Inner Class) Inner Class 是在外部類別中直接宣告的次類別,宣告 方式和一般類別的宣告方式相同。 – 最常使用的方式 可以用 private 、 (default) 、 protected 、 public 等修飾字 來定義 Inner Class 。 – 如果 Inner Class 定義成 private ,外圍類別以外的其 他類別就無法使用該 Inner Class 了。 class OuterClass2{ //Other Code Here public class InnerClass2{ }

26 1-26 Right implements class Computer{ // 外圍類別 (Enclosing Class) class CPU{ // 內部類別 (Inner Class) 不能與外圍類別名字一樣 /…/ class mathPower{ // 內部類別 (Inner Class) /…/ }// end of mathPower class }// end of class CPU }//end of Computer public class Application{ public static void main(String agrs){ Computer aComputer= new Computer(); // 須產生外圍類別 Computer.CPU aCPU= aComputer.new CPU(); }

27 1-27 靜態內部類別 (Static Inner Class) 宣告內部類別時,如果使用 static 修飾字,則該內部類別 稱為「靜態內部類別 」。 靜態內部類別的記憶體位置獨立配置,不需要先將外圍類 別實體化就可以使用靜態內部類別。 靜態內部類別通常是為了供其他的類別使用 – 在 Inner Class 內可以使用外圍類別的資料。 – 在外圍類別內,必須先將內部類別實體化,才可以使 用內部類別的成員 外圍類別. 內部類別 物件名稱 = new 外圍類別. 內部類別

28 1-28 靜態內部類別 (Static Inner Class) 靜態內部類別無法直接存取外圍類別中的非 static 成員。 靜態內部類別可有 static 成員和非 static 成員。 – static 成員在載入時同樣也配置了記憶體空間,外界可 以直接引用。 – 非 static 成員則必需要先將靜態內部成員實體化後才能 使用。

29 1-29 靜態內部類別 (Static Inner Class) 可否直接使用 外圍類別的 static 成員 可否直接使用外 圍類別的非 static 成員 可否直接讓外 部直接存取 static 巢狀類別 的 static 成 員 可否可 static 巢狀類別 的非 static 成員 可否否

30 1-30 error implements class Computer{ class CPU{ // 非 static 內圍類別 /…/ static class mathPower { //static 內圍類別 /…/ //error, can not 加入 static 內圍類別在非 static 內圍類別 但是可以加入非 static 的內圍類別在 static 內圍類別 ( 如下頁 ) }

31 1-31 Right implements class Computer{ static class CPU{ /…/ class mathPower { /…/ }

32 1-32 Right implements class Computer{ static class CPU{ /…/ interface FloatingCalculating { /…/ } static class mathPower implements FloatingCalculating{ /…/ } public class Application{ public static void main(String agrs){ Computer.CPU aCPU= new Computer.CPU(); //static inner class 只能直接搭配類別 }

33 1-33 error implements class Computer{ static class CPU{ /…/ interface FloatingCalculating{ /…/ } static class mathPower implements FloatingCalculating{ /…/ } public class Application{ public static void main(String agrs){ Computer aComputer= new Computer(); // 產生物件 Computer.CPU aCPU= aComputer.new CPU(); //error, 只能直接搭配不可以搭配物件 }

34 1-34 避開循環參考 「循環參照」是指兩個物件互相參考。 – 例如: A 物件是 B 物件的參考,而 B 物件又是 A 物件的 參考。 循環參照使得物件佔用的資源不被回收,它們會一直佔 用著記憶體直到程式結束為止。 避免循環參照常用的方法是:覆寫 finalize 方法,並在 該方法中將指向其他物件的參考都設定為 null 。

35 1-35 Local inner class class Device{ void showDeviceName(){ } class StorageDevice{ Device makeHardDisk(final String devicename){ //class in the method class HardDisk extends Device { void showDeviceName(){ System.out.println(“ 名稱 ” + devicename); } return new HardDisk(); } public class Application{ public static void main(String[] agrs){ Device devices=new StorageDevice().makeHardDisk(” 硬碟 ”); }

36 1-36 Local inner class Some syntax –How to refer to outer-class object? Use outer-object.this Use this and super

37 1-37 Local inner class example class Device{ // 外圍類別 (Enclosing Class) String devicename=“ 裝置 ”; boolean embedded=false; void showMember(){ } class StorageDevice{ // 內部類別 (Inner Class) boolean embedded; Device makeHardDisk(String manufacturer){ Class HardDisk extends Device{ //local Inner calss void showMember(){ super.devicename; StorageDevice.this.embedded; } } return new HardDisk(); }

38 1-38 匿名類別 (Anonymous Class) 沒有宣告名稱的類別稱為「匿名類別 (Anonymous Class) 」。 宣告的方式是直接在程式中以 new 關鍵字來建立類別實體。 由於該類別並沒有名稱,因此只能使用一次。宣告匿名類 別時也可以定義成員及方法,但是不可以定義 static 成員, 也不能定義建構子。 父類別名稱 物件名稱 = new 父類別名稱 ( 參數 ) { // 匿名類別中的成員與方法 ; };

39 1-39 內部匿名類別可以不宣告類別名稱,而使用 "new" 直接產生一個物件,內部匿名類 別可以是繼承某個類別或是實作某個介面,內部匿名類別的宣告方式如下: new [ 類別或介面 ()] { // 實作 } Object obj = new Object() { public String toString() { return " 匿名類別物件 "; } }; 重新定義 toString() 在檔案管理方面,內部匿 名類別在編譯完成之後會 產生「外部類別名稱 $ 編 號.class 」,編號為 1 、 2 、 3...n ,每個編號 n 的檔案對 應於第 n 個匿名類別 編譯後產生 AnonymousClassDemo.class 與 AnonymousClassDemo$1.class 匿名類別

40 1-40 注意如果要在內部匿名類別中使用外部的區域變數,變數在宣告時必須為 "final" ,例如下面的陳述是無法通過編譯的:.... public void someMethod() { int x = 10; Object obj = new Object() { public String toString() { return String.valueOf(x); } }; System.out.println(obj); }.... 沒有宣告為 final x 不能在匿名類別中使用 local variable x is accessed from within inner class; needs to be declared final 匿名類別

41 1-41 存取修飾字 Use in Class –[ 存取修飾字 ]+class+ 名稱 –Only public, default Use in Method –[ 存取修飾字 ]+[static]+ 傳回值 + 方法名稱 Use in data –[ 存取修飾字 ]+ [static]+ 資料型別 + 名稱 – 區域變數中的生命週期僅存在於這個方法,方 法一但執行完畢,區域變數則自動歸還系統, 因此區域變數不可加上 static

42 1-42 存取修飾字 Public – 每各 class 皆可存取 Default – 同一個 package 的 class 才可以存取 Protected – 同一個 package 的 class 才可以存取 – 不同 package 但是如果有繼承也可存取 可以存取 “ 繼承下來的 ” Private – 同一個 class 才能存取

43 1-43 非存取修飾字 Final – 防止被覆寫,通常用於已經制定好的 API Abstract – 抽象的概念,未被實作的程式碼 – 通常用於開發階段的程式宣告 Synchronized – 該函式對於此一物件,只能被一個執行緒執行存取 Native(*) – 該函式與平台相關的程式碼 Strictfp(*) – 浮點數遵循 IEEE754 的標準

44 1-44 參考資料 物件導向觀念 – http://java.sun.com/docs/books/tutorial/java/concepts/ index.html http://java.sun.com/docs/books/tutorial/java/concepts/ index.html


Download ppt "Course Introduction CLASS III. Outline “equals” and “==“, the equality problem The root of the class hierarchy Modifier Nested classes –Instance nested."

Similar presentations


Ads by Google