[Java] 6.7. 介面 張貼者: 羅康鴻 日期: 6月 29, 2021 取得連結 Facebook X Pinterest 以電子郵件傳送 其他應用程式 介面,行為的規格書。 image/svg+xml6.7. 介⾯ - interface 第 1 步, interface 將員⼯的能⼒介⾯化 第 2 步, implements 實作不同能⼒的介⾯ 介⾯,可多重繼承 介⾯,即是⼀種型別 class Superman extends Programmer , Tester , Artist { } 編譯時發⽣錯誤 Superman.java:1: error: '{' expected class Superman extends Programmer, Tester, Artist{ ^ 1 error interface Programmable { void code (); void debug (); } interface Testable { void test (); } interface Drawable { void draw (); } class Programmer extends Employee implements Programmable { // 略過⼀些程式 public void code (){ System.out.println( " 我 " + name + " 正在寫程式 ⋯ " ); System.out.println( "Coding By" + name); System.out.println( " 我 " + name + " 終於寫完程式了 ⋯ " ); } public void debug (){ System.out.println( " 我 " + name + " 正在除錯 ⋯ " ); System.out.println( "Debugging By" + name); System.out.println( " 我 " + name + " 終於抓出蟲了 ⋯ " ); } } class Tester extends Employee implements Testable { // 略過⼀些程式 public void test (){ System.out.println( " 我 " + name + " 正在測試系統 ⋯ " ); System.out.println( "Testing By" + name); System.out.println( " 我 " + name + " 終於測試完了 ⋯ " ); } } class Artist extends Employee implements Drawable { // 略過⼀些程式 public void draw (){ System.out.println( " 我 " + name + " 正在畫圖畫 ⋯ " ); System.out.println( "Drawing By" + name); System.out.println( " 我 " + name + " 終於畫完了 ⋯ " ); } } class Superman extends Employee implements Programmable , Testable , Drawable { // 略過⼀些程式 public void debug (){ System.out.println( " 程式設計師 " +name); System.out.println( " 正在除錯中 ⋯ " ); System.out.println( " 除錯完成 ⋯ " ); } public void test (){ System.out.println( " 測試⼈員 " +name); System.out.println( " 正在測試中 ⋯ " ); System.out.println( " 測試完成 ⋯ " ); } public void draw (){ System.out.println( " 美⼯⼈員 " +name); System.out.println( " 正在繪圖中 ⋯ " ); System.out.println( " 繪圖完成 ⋯ " ); } } interface FullFunction extends Programmable , Testable , Drawable { } class Superman extends Employee implements FullFunction { // 略過⼀些程式 public void code (){ System.out.println( " 程式設計師 " +name); System.out.println( " 正在寫程式中 ⋯ " ); System.out.println( " 程式寫作完成 ⋯ " ); } public void debug (){ System.out.println( " 程式設計師 " +name); System.out.println( " 正在除錯中 ⋯ " ); System.out.println( " 除錯完成 ⋯ " ); } public void test (){ System.out.println( " 測試⼈員 " +name); System.out.println( " 正在測試中 ⋯ " ); System.out.println( " 測試完成 ⋯ " ); } public void draw (){ System.out.println( " 美⼯⼈員 " +name); System.out.println( " 正在繪圖中 ⋯ " ); System.out.println( " 繪圖完成 ⋯ " ); } } class Main { public static void main( String [] args){ Programmer p = new Programmer (); Tester t = new Tester (); Artist a = new Artist (); Superman s = new Superman () p.name= “Jack" ; t.name = "Eric" ; a.name= "Marry" ; s.name= "Conrad" ; Employee [] allEmps = { p , t , a , s }; for ( Employee e : allEmps ){ if ( e instanceof Programmable ) System.out.println( e.name+ " 擁有可程式的能⼒ " ); if ( e instanceof Testable ) System.out.println( e.name+ " 擁有可測試的能⼒ " ); if ( e instanceof Drawable ) System.out.println( e.name+ " 擁有可繪圖的能⼒ " ); if ( e instanceof FullFunction ) System.out.println( e.name+ " 擁有全能⼒的能⼒ " ); } } } interface Programmable { public static final String CHARACTER = “ 邏輯能⼒強 " ; void code(); void debug(); } interface Testable { public static final String CHARACTER = “ 很有耐⼼ " ; void test(); } interface Drawable { public static final String CHARACTER = “ 有天份的 " ; void draw(); } interface FullFunction extends Programmable , Testable , Drawable { public static final String CHARACTER = “ 上帝的玩笑 " ; } interface Programmable { void code(); void debug(); } class Main { public static void main( String [] args){ Programmable p = new Programmable (); } } 編譯時發⽣錯誤 Main.java:3: error: Programmable is abstract; cannot be instantiated Programmable p = new Programmable(); ^ 1 error J6_7_1 – Superman.java 1. interface 關鍵字表⽰介⾯的意思。其是⽤來定義介⾯的。 J6_7_2 – Programmable.java 1. 我們將這個萬能的員⼯類別( Superman ),取名叫 Superman 。 在3個不同⾓⾊的能⼒都會的情況下,那這真的是很 Superman… 2. 您希望透過 extends 與逗點( , )的⽅式,⼀次繼承多個不同⾓⾊的員⼯類 別,以取得每個類別的所有⽅法,這樣這個超級員⼯類別就會擁有所有不同⾓⾊ 員⼯的能⼒。但 … 若如此作,在編譯的時候,編譯器會告訴您這個語法是不對 的,因為1個類別只能以單⼀繼承的⽅式,繼承另⼀個類別。那 … 有沒有⼀個好 ⽅法,可以讓這個超級員⼯可以同時擁有多項能⼒呢?這⼜要如何作到? public abstract public abstract public abstract public abstract J6_7_2 – Testable.java J6_7_2 – Drawable.java 2. 將程式設計師( Programmer )的能⼒以介⾯的⽅式 定義,⽽這項能⼒就稱為 “ 可程式 ”-Programmable 。 3. 這是在 “ 可程式 ” 介⾯下所擁有的⽅法,⽤以表⽰在可程式 的能⼒下,將擁有寫程式( code() )與除錯( debug() )兩 個⾏為。在介⾯上的⽅法是不需要、也不能有⽅法本體的,原 因是在介⾯中的⽅法皆是抽象的,因此不能有⽅法本體。 6. public 與 abstract 兩個修飾關鍵字,是⼀定會加在⽅法上的,換句話說,即使不寫 public 與 abstract ,編譯器會幫您加上。因此所有在介⾯上的⽅法,⼀定是公開化且抽象化的。 4. 將測試⼈員( Tester )的能⼒以介⾯的⽅式定義,⽽這項能⼒就稱為 “ 可測式 ”- Testable ,在這個能⼒下有個測試的⾏為,因此有⼀個測試⽅法( test() )。 5. 將美⼯⼈員( Artist )的能⼒以介⾯的⽅式定義,⽽這 項能⼒就稱為 “ 可繪圖 ”-Drawable 。在這個能⼒下有個繪 圖的⾏為,因此有⼀個繪圖⽅法( draw() )。 public 關鍵字是⽤來描述是否進⾏公開化,當⽅法進⾏公開化時,表⽰這個 ⽅法是可以公開開放使⽤的,關於 public 關鍵字的詳細⽤法可參考 ” 將類別 分類 ” 章節。 提 ⽰ J6_7_2 – Programmer.java 1. 使⽤ implements 關鍵字,讓程式設計師類別( Programmer )實作可程式 介⾯( Programmable ),同時實作可程式介⾯上的寫程式⽅法( code() )與 除錯⽅法( debug() ),如此程式設計師類別就擁有可程式的能⼒了。 2. 使⽤ implements 關鍵字,讓測試⼈員類別 ( Tester )實作可測試介⾯( Testable ),同時實作可 測式介⾯上的測試⽅法( test() ),如此測試⼈員類別就 擁有可程式的能⼒了。 3. 使⽤ implements 關鍵字,讓美⼯⼈員類別( Artist )實 作可繪圖介⾯( Drawable ),同時實作可繪圖介⾯上的繪圖⽅ 法( draw() ),如此美⼯⼈員類別就擁有可繪圖的能⼒了。 J6_7_2 – Tester.java J6_7_2 – Ar A st.java J6_7_2 – Superman.java 4. 這是超級員⼯類別( Superman )。 5. 為了讓超級員⼯類別可以⼀次擁有多項能⼒,這時可實作多個介 ⾯-可程式介⾯( Programmable )、可測試介⾯( Testable ) 與可繪圖介⾯( Drawable ),只要使⽤逗號( , )的⽅式將不同的 介⾯隔開,如此超級員⼯即可實作多個介⾯,擁有多項能⼒。 6. 最後實作每個介⾯上的⽅法,實際的 透過⽅法本體描述各⽅法進⾏的⽅式。 J6_7_3 – FullFunc A on.java 1. 新的全能⼒介⾯- FullFunction 。 2. 介⾯與介⾯在進⾏繼承時,是 透過 extends 關鍵字來達成,並 非是 implements 關鍵字。 3. 全能⼒介⾯( FullFunction )可以⼀ 次繼承⾃多個介⾯,只要使⽤逗號( , )的 ⽅式即不同的介⾯隔開即可。如此這個全能 ⼒介⾯即可以其他介⾯的⽅法繼承下來。 5. 這是超級員⼯類別( Superman )。 4. 介⾯是可以透過 extends 關鍵字進⾏多重繼承的。 6. 因為實作全能⼒介⾯( FullFunction )後,即必須改寫可 程式介⾯、可測試介⾯與可繪圖介⾯( Programmable 、 Testable 、 Drawable )上的所有⽅法,原因就出在全能⼒介 ⾯繼承了可程式介⾯、可測試介⾯與可繪圖介⾯。 J6_7_3 – Superman.java J6_7_4 – Main.java 1 . 建立程式⼈員、測試⼈員、美⼯⼈員與超級員⼯的物件 ( Programmer 、 Tester 、 Artist 與 Superman )。 2. 將程式⼈員、測試⼈員、美⼯⼈員與超級員⼯的物件放入⾄員 ⼯型別的陣列中,這時所有的物件皆將會轉型為員⼯型別的物件。 3. 接著透過 for 依序的取出每個員⼯物件。 4. 雖然取出的每個物件皆是員⼯型別的⽅式取出,但因為介 ⾯也是型別的⼀種,因此可以透過 instanceof 關鍵字來測試 物件所擁有的型別。相對的,當你要找出特定能⼒的員⼯時, 就可以依照介⾯來篩選員⼯,⽽不是依照類別來篩選員⼯。 J6_7_6 – Programmable.java J6_7_6 – Main.java 1. abstract 關鍵字是編譯器為所有的介⾯加上的修飼字。即使 不寫編譯器也會偷偷的為介⾯加上。如在此的 “ 可程式介⾯ ” - Programmable ,編譯器即會⾃動加上 abstract 關鍵字。 2. 因為介⾯是抽象化的( abstract ),因此當您嘗試 透過 new 建立介⾯物件時,編譯器會發⽣錯誤,告訴您 介⾯是抽象化的,您不可建立抽象化型別的物件。 J6_7_5 – Programmable.java 1 . 當屬性是靜態化( static )且確定化( final ) 時,這時功能即同等於常數的功能,它的內容是不會變 的,因此像這⼀類別屬性通常以⼤寫的⽅式來表⽰。 2. 描述可程式介⾯( Programmable ) 的特性是要邏輯能⼒強。 3. 描述可測試介⾯( Testable ) 的特性是要很有耐⼼的。 4. 描述可繪圖介⾯( Drawable ) 的特性是要有藝術天份的。 5. 描述可全能⼒介⾯( FullFunction ) 的特性是這其實是上帝的玩笑。 6. public 、 stataic 與 final 三個修飾關鍵字,是⼀定會加在屬性上的。 換句話說,即使不寫 public 、 stataic 與 final ,編譯器會幫您加上。因此 所有在介⾯上的屬性,⼀定是公開化、靜態化且確定化的。⽽這些屬性的⽬的 只有⼀個,就是⽤來描述介⾯的特徵,因此是直接依附在介⾯上。 J6_7_5 – Testable.java J6_7_5 – Drawable.java J6_7_5 – FullFunc A on.java ⼩⼼,介⾯不可透過 new 建立實體物件 有個多才多藝的員⼯多好,這樣就可以不⽤請這麼多不同⾓ ⾊的員⼯了,但這可能嗎? 1 1 public abstract public abstract public abstract 1 1 介⾯也可擁有屬性, 但 … 必須是公開化、確定化且靜態化的 留言
留言
張貼留言