1 / 50

Managing Inheritance

Managing Inheritance. Lecturer :楊昌樺. Outline. 存取控制( Access Control ) static 關鍵字 實體成員與類別成員 static 初值設定區塊 Your Turn 物件導向語言三大特性 封裝 ( Encapsulation) 繼承( Inheritance ) 同名異型( Polymorphism ) Overriding Overloading super 關鍵字 Java 物件祖先: Object 類別 Final Classes and Methods Your Turn.

elroy
Download Presentation

Managing Inheritance

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. Managing Inheritance Lecturer:楊昌樺

  2. Outline • 存取控制(Access Control) • static 關鍵字 • 實體成員與類別成員 • static 初值設定區塊 • Your Turn • 物件導向語言三大特性 • 封裝 (Encapsulation) • 繼承(Inheritance) • 同名異型( Polymorphism ) • Overriding • Overloading • super 關鍵字 • Java 物件祖先:Object 類別 • Final Classes and Methods • Your Turn

  3. 存取控制(Access Control) • 控制存取的關鍵字 • public、protected、private • 置於類別或成員宣告之前 • 若沒有指定任何存取權限,表示此類別或成員僅供相同類別庫的其他類別使用,稱為 package access層級 • 將類別或成員設定為 package access 層級的好處是可使同在一個類別庫下的每個類別互相使用成員

  4. 存取控制(Access Control) • public • 任何類別皆可存取 • default • packetage access • protected • 允許宣告的類別、子類別與同一個套件中的類別使用 • private • 只有在類別內部可以存取 • 對於成員變數,通常設定為 private 權限,再透過 methods,如 get/set 來存取資料

  5. 存取控制(Access Control) • Class Access • 類別不可設定為 private 或 protected • 若為了避免他人任意使用 constructors 建立物件 • 可將 constructors 設定為 private • 另外提供 static 的 methods 建立物件、複製物件 • main() 必須由程式外部的程式碼來呼叫(Java 執行時期系統),所以 main() 必須為 public • 設計存取秘訣: • 設定適合但最嚴苛的存取等級。因此,盡量使用 private。 • 如此在修改成員變數內容時,只能透過 method。除非,在評估設為 public後會對於程式效能有顯著提升的情況。

  6. Package與示範存取的範例 用eclipse功能 new->package, 建立Package “One” 在One裡面新增類別 “Alpha” Alpha類別只是一個單純的物件類別 在One裡面新增類別“DeltaOne” DeltaOne類別用同Package的Alpha類別建立物件 新增Package “Two” 新增類別“Delta Two” DeltaTwo類別用別Package的Alpha類別建立物件

  7. 存取控制(Access Control)範例 • Example: Alpha.java private int iamprivate = 1; int iampackage = 2; //package access protected int iamprotected = 3; public int iampublic = 4; private void privateMethod() { System.out.println("iamprivate Method"); } void packageMethod() { // default: package access System.out.println("iampackage Method"); } protected void protectedMethod() { System.out.println("iamprotected Method"); } public void publicMethod() { System.out.println("iampublic Method"); }

  8. 存取控制(Access Control)範例 • Example: DeltaOne.java package One; public class DeltaOne { public static void main(String[] args) { Alpha a = new Alpha(); //a.privateMethod(); //illegal a.packageMethod(); //legal a.protectedMethod(); //legal a.publicMethod(); //legal //System.out.println("iamprivate: “ + a.iamprivate); //illegal System.out.println("iampackage: “ + a.iampackage); //legal System.out.println("iamprotected: “ + a.iamprotected); //legal System.out.println("iampublic: “ + a.iampublic); //legal } }

  9. 存取控制(Access Control)範例 • Example: DeltaTwo.java package Two; import One.*; public class DeltaTwo { public static void main(String[] args) { Alpha alpha = new Alpha(); //alpha.privateMethod(); //illegal //alpha.packageMethod(); //illegal //alpha.protectedMethod(); //illegal alpha.publicMethod(); //legal //System.out.println("iamprivate: “ + alpha.iamprivate); //illegal //System.out.println("iampackage: “ + alpha.iampackage); //illegal //System.out.println("iamprotected: “ + alpha.iamprotected); //illegal System.out.println("iampublic: “ + alpha.iampublic); //legal } }

  10. static 關鍵字 • 實體成員與類別成員 • 變數或 methods 若宣告為 static,則此變數或 methods 即為類別變數(class variables)或類別方法(class methods) • 宣告為 static 的變數或 methods 不屬於任何此類別的物件,乃此類別所有物件共同擁有 • 宣告 • static DataType VarName; • static ReturnTypeMethodName(Arg List) • 使用 • ClassName.VarName • ClassName.MethodName(Arg List)

  11. static 關鍵字 • 使用時機 • 無論此類別擁有多少物件,這份資料只需要一份 • 某種方法在實行時,與個別的物件無關 • 即便是沒有任何物件被產生,依舊可以使用被宣告成 static 的變數與 methods;相反的,instance variables 與 methods 必須透過物件才能實施 • 在 static methods 裡,無法直接呼叫 instance methods 或直接使用 instance variables • 因為 instance variables 與 methods 必須透過物件才能實施

  12. static 關鍵字 • 被用 static 宣告的類別方法和類別變數,意思上就像是其他程式語言中的全域函數(global functions)和全域變數(global variables),例如:C語言 • 因此,如果要很多宣告成 static 的方法或變數的話,必須要謹慎使用!

  13. static 關鍵字- 實體成員與類別成員

  14. static 關鍵字 - 實體成員與類別成員 • Example: StaticDemo.java public class StaticDemo { public int instanceInteger = 0; public int instanceMethod() { return instanceInteger; } public static int classInteger = 0; public static int classMethod() { return classInteger; } public static void main(String[] args) { … } }

  15. static 初值設定區塊 • class 變數或是實體變數,可以直接設定初值 public class BedAndBreakfast { public static final int MAX_CAPACITY = 10; //initialize to 10 private boolean full = false; //initialize to false } • 限制: • 不能用 if-else 來設定初值 • 設定初值時,不可以處理 exceptions • 若發生 exceptions,也無法做錯誤處理

  16. static 初值設定區塊 • static 初值設定區塊 • Java 允許將 static 變數集合起來進行初始化動作 • 語法: • 因為 x 和 isOK 都是 class 變數,無法在建構元中設定初值,且利用 static 初設設定區塊可以處理 exceptions。 • class TestClass{ • static int x; static boolean isOK; • static{ • x = 100; //static int x; • isOK = false; // static isOK; • } • }

  17. 建構元(Constructors) • 修飾建構元的關鍵字 • private • 如果一個類別裡所有的建構元都是宣告成 private 的話,那這個類別應該會有 public 的類別方法(class method),讓其他類別建立此類別之物件 • protected • 只有該類別的 subclass,或是屬同一個 package 裡的類別,才可以使用此建構元 • public • 所有類別都可以使用此建構元 • 預設 • 只有同一個 package 裡的類別,才能使用此建構元

  18. Your Turn • 整理上次寫的 Rectangle 類別 • 此類別必須完成下列要求 • 此類別不提供constructor 供外部存取(為 private) • 要提供三個 class methods 來建立 Rectangle 物件 • 第一個是使用預設長寬:長 8,寬 4(createRect) • 第二個是可以讓使用者自行指定(createRect) • 第三個複製矩形(cloneRect) • 顯示目前的長、寬之值(showLW) • 取得目前矩形之面積(getArea) • 畫矩形,由 * 構成邊長(drawRect)

  19. Your Turn • Hint // 建構元 private Rectangle(){ … } // 另一個建構元 private Rectangle(int length, int width){ … } // 此建構元提供給 cloneObj 用,用以複製 private Rectangle(Rectangle obj){ … } // 提供一個可以製造長方形的 class method static Rectangle createRect() { … } // 提供一個可以製造且自行設定長方形的 class method static Rectangle createRect(int len, int width) { … } // 複製此長方形 static Rectangle cloneRect(Rectangle obj) { … } // 顯示現在的長、寬 void showLW() { … } // 取得現在的面積 double getArea(){ … } // 畫出此長方形 void drawRect(){ … }

  20. 物件導向三大特性 • 封裝 (Encapsulation) • 設計 Class,決定要將哪些屬性,方法,事件封入類別中的動作叫做封裝。 • 讓程式碼可以以Class為單位分類,並讓文件撰寫可以用物件導向模式撰寫 (e.g., class diagram)。 • 繼承 (Inheritance) • 設計 Class 時,先利用現存 Class 作為 “祖先”,再加以增加或修改功能的動作叫繼承。 • 讓程式碼可以輕易地重複使用,並形成樹狀結構之class diagram。 • 同名異型 (Polymorphism) • 呼叫相同的函式,卻會出現不同的行為的現象,稱為同名異型。分為 “overriding” 及 “overloading”。 • 擴充既有程式碼之功能。

  21. 屬性: 身高 體重 年齡 方法: 走路 跑步 事件: 被打 驚嚇 開心 物件導向三大特性 • 封裝 (Encapsulation) • 設計一個 Class 的屬性,方法,事件,稱為 “封裝” 一個類別。 人類

  22. 屬性: 身高 體重 年齡 方法: 走路 跑步 貝多芬 事件: 被打 驚嚇 開心 物件導向三大特性 • 繼承 (Inheritance) • 設計 Class 時,先利用現存 Class 作為 “祖先”, • 再加以增加或修改功能的動作叫繼承。 • 讓程式碼可以輕易地重複使用,並形成樹狀結構之class diagram 人類 = 165 = 80 = 45 音樂家 作曲 發表

  23. 屬性: 身高 體重 年齡 方法: 走路 跑步 事件: 被打 驚嚇 開心 物件導向三大特性 • 同名異型 (Polymorphism) • Overriding • 若繼承下來後,不滿意祖先定義的方法,子孫可以在繼承以後重新改寫,稱為 Overriding。 人類 人類.走路() { 約一分鐘三十步 } 音樂家 音樂家.走路() { 約一分鐘十步 } 作曲 同樣是呼叫 “走路”, 宣告成人類與音樂家 就是不一樣。 發表

  24. 屬性: 身高 體重 年齡 方法: 走路 跑步 事件: 被打 驚嚇 開心 物件導向三大特性 • 同名異型 (Polymorphism) • Overloading • 同一份函式,準備多種定義,以供各種場合呼叫,稱為Overloading。 人類 音樂家.作曲(“王先生”) 音樂家 作曲 作曲 (委託人) 自動判斷

  25. 封裝 (Encapsulation) • 將資料(屬性)與方法(行為)封裝在一個物件裡頭,物件裡頭的資料與方法被緊緊的綁在一起,並擁有資訊隱藏(Information hiding)的特性。 • Example: TimeDemo.java class Time {   private int hour;   private int minute;   private int second;   public Time() { … }   public void setTime(int hh,int mm,int ss) { … }   public String toString() { … }}

  26. 繼承(Inheritance) • 繼承概念圖

  27. 繼承(Inheritance) • 語法:class ClassName extends BaseClass • 例如:class Line extends GraphicsObject • Base Class(SuperClass):基底類別、父類別 • Derived Class(Subclass):衍生類別、子類別 • Java 理論上不支援多重繼承,也就是說,一個子類別只能有一個父類別。 • 子類別將會繼承到父類別中所有可以存取的成員,包括:變數以及方法 • 注意:建構元(constructor)無法被繼承 • Java 中每個物件的總祖先:Object 類別( java.lang.Object )

  28. 繼承(Inheritance) • 可繼承成員 • Superclass 中宣告為 public或 protected的成員。 • 如果 Subclass 與 Superclass 在同一個 package 中,會繼承未做任何存取控制宣告的成員。 • 不可繼承成員 • 如果 Subclass 與 Superclass 在不同 package,所有未宣告有效範圍的成員全部不繼承。(因為預設式 package access) • Superclass 中宣告成 private 的成員

  29. 繼承(Inheritance) • Example: Dog.java public class Dog { // 屬性 (Variables) private String name; private String color; private int age; // 建構元 (Constructor) public Dog(String name, String color, int age){ this.name = name; this.color = color; this.age = age; } // 方法 (Methods) public void bark() { … } public void handshake() { … } public void rollover(int theTimes) { … } … }

  30. 繼承(Inheritance) • Example: Pomer.java public class Pomer extends Dog { // 建構元 public Pomer(String name, String color, int age) { super(name, color, age); } // 新的方法 public void proud() { System.out.println("哼..."); } }

  31. 同名異型( Polymorphism ) • 覆蓋 Overriding • 若繼承下來後,不滿意祖先定義的方法,子孫可以在繼承以後重新改寫,稱為 Overriding。 • 可覆蓋成員 • 任何與 Superclass 同名的成員 • 必覆蓋成員 • Subclass 一定要覆蓋 superclass 中宣告為 abstract 的 methods,除非 subclass 本身也是 abstract 類別 • 不可覆蓋成員 • Subclass 不可覆蓋 superclass 的 final methods

  32. 同名異型( Polymorphism ) • 覆蓋 Overriding • 將 父類別 Dog 的 Handshake 方法 Override 掉 class Pomer extends Dog { // 建構元 public Pomer (String name, String color, String age) { super(name, color, age); } // 將父類別 Dog 中原有的 handshake() 方法 Override 掉 public void handshake() { System.out.println("你的手洗了嗎?"); } public void proud() { System.out.println(“哼..."); } }

  33. 同名異型( Polymorphism ) • 過載 Overloading • 同一份函式,準備多種定義,以供各種場合呼叫,稱為Overloading。 • 建構元也可以利用參數的不同,來達成 overloading

  34. 同名異型( Polymorphism ) • 建構元的 Overloading class Pomer extends Dog { // 具有 overloading 的建構元 public Pomer() { super(“GoodDog”, “Red”, 12); } public Pomer (String name, String color, String age) { super(name, color, age); } // override 父類別 Dog 中的 handshake() 方法 public void handshake() { System.out.println("你的手洗了嗎?"); } public void proud() { System.out.println(“哼..."); } }

  35. 同名異型( Polymorphism ) • 方法的 Overloading • class Pomer extends Dog { • // 建構元 • public Pomer (String name, String color, String age) { • super(name, color, age); • } • // 具有 overloading 的 rollover() • public void rollover() { • for (int i=1; i<=5; i++) • System.out.println("我滾 " + i + " 次"); • } • public void rollover(int thetimes) { • for (int i=1; i<=thetimes; i++)…

  36. super 關鍵字 • this & super 關鍵字 • this:指的是目前的 class • super:指的是父類別 • 使用 super 來呼叫父類別中的方法 語法:super.methodName(argList); • super.Bark(); • super.Rollover(5); • 若子類別中沒有建構元(constructor),可單用 super 來呼叫父類別中的建構元 語法:super(argList);

  37. Java 物件祖先:Object 類別 • Java 中的所有物件,全部繼承自 java.lang.Object • 只要程式師沒有以 extends 指定 繼承之物件,Java 會自動用 Object 作為所有物件的父物件。

  38. Java 物件祖先:Object 類別 • 以下是 Object 中的方法,可能是您想 Overriding 的: • clone() • equals() • toString() • finalize() • 以下是 Object 中,宣告為 final 的方法,不可以 Overriding: • getClass() • hashCode() • notify() • notifyAll() • wait()

  39. Java 物件祖先:Object 類別 • clone() • 原始宣告:protected Object clone() throws CloneNotSupportedException • 作用:複製一份物件本身,並傳回去。 • 要求: • 要讓類別成為可複製類別的最簡單方法:在類別宣告最後加上 implements Cloneable • Object 提供的 clone() 功能很適合,但有些類別必須要覆蓋 clone(),才能提供正確的複製功能

  40. Java 物件祖先:Object 類別 • equals() • 原始宣告:public boolean equals(Object obj); • 作用:比較兩個物件的內含值是否相等。 • 要求:無 • hashCode() • 回傳的 int 數值,代表物件在 hash table 裡對應位置。 • 傳回物件在 “雜湊表” (Hash Table) 中的索引值。通常配合 java.util.Hashtable 使用

  41. Java 物件祖先:Object 類別 • finalize() • 原始宣告:protected void finalize() throws Throwable • 作用:物件離開其有效範圍時,一定會被叫用的函式。用來清除本物件以 new 霸佔的記憶體。 • 系統會自動呼叫 finalize(),因此大部分的類別都不需要覆蓋 finalize() • 所以在 Java 中,要拋棄一個記憶體,只要: • ObjA = null; • ObjB = null;

  42. Java 物件祖先:Object 類別 • toString() • 原始宣告:public String toString(); • 作用:傳回一個此物件的描述字串 • toString() 對除錯(debug)很有幫助 System.out.println(new Double(Math.PI).toString());

  43. Java 物件祖先:Object 類別 • 改寫從Object物件繼承來的toString()方法 • Example: TimeDemo.java class Time { … public String toString() { return (hour+":"+(minute<10? "0" : "")+minute+ ":"+(second<10? "0" : "")+second); } }

  44. Java 物件祖先:Object 類別 • getClass() • 原始宣告:public final Class getClass(); • 作用:可取得一個類別的所有資訊。包括類別名稱,父類別名稱,實作介面名稱,所有成員變數及成員函式,甚至於可以由取回的 class 資料個體化一個物件。 • 要求:不准覆寫 (Overriding) • 傳回值:傳回 java.lang.Class。傳回後,您就可以使用所有 java.lang.Class 的屬性與方法。

  45. Final Classes and Methods • Final Classes • 定義 • 一個不准被別人繼承的類別稱為 final class • 宣告 語法:AccessLevel final class ClassName • 如:final class ColorPoint • 使用時機 • 安全性 • 駭客最常用來破壞系統的方式,建立某個類別的 subclass,然後將原來類別的主體置換成自己的主體。 • 當一個類別已經十分完美時

  46. Final Classes and Methods • Final Classes final class A {//…}// The following class is illegal.class B extends A //錯誤!無法形成A的子類別{          //…}

  47. Final Classes and Methods • Final Methods • 定義 • 一個不准被 subclass 覆寫(Overriding)的函式稱為 final method • 宣告 • 語法:final 傳回值型態 函式名稱 (參數, …); • 使用時機 • 當覆寫(Overriding)會出現問題時。

  48. Final Classes and Methods • Final Methods class A { final void meth() {      System.out.println("This is a final method.");   }}class B extends A {   void meth( ) //這裡開始會出現錯誤!不能覆蓋。 {             System.out.println("Illegal!");   }}

  49. 實例講解 • 程式:InheritanceDemo.java • 類別成員(Class Method) • 繼承(Inheritance) • Overriding • Overloading • super

  50. Your Turn • 試用 Dog 類別產生一個 如GoldenRetriever (黃金獵犬)類別 • 具有兩個建構元(Overloading) • GoldRetriever()  預設:如流浪狗、金色、5 歲不傳任何參數時、呼叫overloading的建構元呼叫方式如this(“流浪狗”,“金色”,5); • GoldRetriever(String theName, String theColor, int theAge)初始化其實跟Dog父類別一樣, 呼叫方式如 super(theName,theColor,theAge); • 多一個方法 smile(),如印出 “^_^” • Override 原本 Dog 類別中的 bark() 方法,如印出 “嘻嘻~” • Override Object 中的 toString(),如印出“我是一隻可愛的黃金獵犬!”

More Related