1 / 44

Course Introduction

Course Introduction. CLASS III. Outline. “equals” and “==“, the equality problem The root of the class hierarchy Modifier Nested classes Instance nested class Static nested class. Object equal?. 比較兩個東西是否相等, JAVA 程式碼最常用到的方法不外乎下列兩種 : “==“ 呼叫函式 equals()

neil
Download Presentation

Course Introduction

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. 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

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

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

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

  6. 相等的迷思程式碼 class Student { String name; String id; public boolean equals(Objectobj) { 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

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

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

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

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

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

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

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

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

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

  19. 繼承 • interface(介面) • Java CLASS裡沒有多重繼承,若要用到多重繼承,必須以interface為替代方案

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

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

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

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

  29. 靜態內部類別 (Static Inner Class)

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

  31. Rightimplements class Computer{ static class CPU{ /…/ class mathPower { /…/ } } }

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

  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. Local inner class • Some syntax • How to refer to outer-class object? • Use outer-object.this • Use this and super

  37. Local inner classexample class Device{ //外圍類別 (Enclosing Class) String devicename=“裝置”; booleanembedded=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. 匿名類別 (Anonymous Class) 沒有宣告名稱的類別稱為「匿名類別 (Anonymous Class)」。 宣告的方式是直接在程式中以new關鍵字來建立類別實體。 由於該類別並沒有名稱,因此只能使用一次。宣告匿名類別時也可以定義成員及方法,但是不可以定義static成員,也不能定義建構子。 父類別名稱 物件名稱 = new 父類別名稱(參數) { //匿名類別中的成員與方法; };

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

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

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

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

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

More Related