JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java 新手區 » Object/物件導向  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 給新手 - 介面(interface) [精華]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-13 01:48 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
這篇文章老實說我覺得寫得不是很好,因為寫得很零碎,且當中涉及一些觀念性的問題,再加上我對於介面的使用時機一直不是能很精確的掌握!

因為另一個討論串討論到多型,我想,還是將它貼過來接受批評,以釐清我的一些觀念,這篇可以與另一些「給新手 - 抽象類別、抽象函式」共同來看,畢竟抽象類別(abstract class)與介面(interface)新手容易搞混,老手也不見得一定能體會。

==========================================================================

interface可以讓我們建立完全抽象的介面,介面的宣告是使用interface關鍵字,宣告方式如下:
1
2
3
4
5
[public] interface 介面名稱 {
    權限限定 傳回型態 方法(參數列);
    權限限定 傳回型態 方法(參數列);
    // ....
}


一個宣告interface的例子如下所示:
1
2
3
interface ServerListener {
    public void listen();
}


當我們宣告類別時,我們可以使用implements關鍵字來一併指定要實作哪個介面,介面中所有定義的方法都要實作,例如:
1
2
3
4
5
6
7
8
9
10
11
12
class BigServer implements ServerListener {
    private String name;
                                                                                
    public BigServer(String name) {
        this.name = name;
    }
                                                                                
    // 實作介面方法
    public void listen() {
        System.out.println("Now, BigServer " + name + " is listening....");
    }
}


下面這個程式示範一些interface的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
interface ServerListener {
    public void listen();
}
 
class BigServer implements ServerListener {
    private String name;
 
    public BigServer(String name) {
        this.name = name;
    }
 
    // 實作介面方法
    public void listen() {
        System.out.println("Now, BigServer " + name + " is listening....");
    }
}
 
class TinyServer implements ServerListener {
    private String name;
                                                                                
    public TinyServer(String name) {
        this.name = name;
    }
                   
    // 實作介面方法                                                             
    public void listen() {
        System.out.println("Now, TinyServer " + name + " is listening....");
    }
}
 
public class UseInterface {
    public static void main(String[] args) {
        BigServer bigServer = new BigServer("Big Brother");
        TinyServer tinyServer = new TinyServer("Small Boy");
 
        bigServer.listen();
        tinyServer.listen();
    }
}


執行結果:
1
2
3
$ java UseInterface
Now, BigServer Big Brother is listening....
Now, TinyServer Small Boy is listening....


在C++中可以使用多重繼承,但在Java中只能單一繼承,也就是一次只能繼承一個類別,Java使用interface來達到某些多重繼承的目的,您可以一次實作多個介面,就像是同時繼承多個抽象類別,實作多個介面的方式如下:
1
2
3
class 類別名稱 implements 介面1, 介面2, 介面3 {
    // 介面實作
}


當您實作多個介面時,記得實作每一個介面中所定義的方法。

介面還可以用來定義介面常數,其作用有些類似C++後的列舉功能,一個實例如下所示:
1
2
3
4
5
interface OperateConstants {
       public static final TurnLeft = 1;
       public static final TurnRight = 2;
       public static final Shot = 3;
}


宣告以上的類別之後,我們就可以在程式中直接使用OperateConstants.TurnLeft之類的名稱來取代常數值,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
public void doOp(int op) {
    switch(op) {
        case OperateConstants.TurnLeft:
            System.out.println("向左轉");
            break;
        case OperateConstants.TurnRight:
            System.out.println("向右轉");
            break;
        case OperateConstants.Shoot:
            System.out.println("射擊");
            break;
    }
}


介面其實與抽象類別的作用類似,但有一些地方不同,例如抽象類別中允許您先實作某些方法,但介面定義中是完全不實作,它只定義方法名稱,介面常用於規範統一的操作介面,像在視窗程式中,就使用介面來實作指定的事件處理傾聽者。

抽象類別類似於抽象資料型態,它定義任何的子類別或子型態所共同擁有的特性,而介面則定義一組協定,所有實作它的類別都必須遵守的協定,介面可以保證實作它的類別一定會實作所定義的方法。

介面也可以用於宣告型態變數,實作介面的物件可以指定給該變數,一個例子如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
interface ServerListener {
    public void listen();
}
 
class BigServer implements ServerListener {
    private String name;
 
    public BigServer(String name) {
        this.name = name;
    }
 
    // 實作介面方法
    public void listen() {
        System.out.println("Now, BigServer " + name + " is listening....");
    }
}
 
class TinyServer implements ServerListener {
    private String name;
                                                                                
    public TinyServer(String name) {
        this.name = name;
    }
                   
    // 實作介面方法                                                             
    public void listen() {
        System.out.println("Now, TinyServer " + name + " is listening....");
    }
}
 
public class UseInterface {
    public static void main(String[] args) {
        ServerListener serverListener = new BigServer("Big Brother");
        serverListener.listen();
 
        serverListener = new TinyServer("Small Boy");
        serverListener.listen();
    }
}


執行結果:
1
2
3
$ java UseInterface
Now, BigServer Big Brother is listening....
Now, TinyServer Small Boy is listening....


就如這個程式所示的,我們可以使用interface來統一呼叫的介面,這也是實現多型的一種方式。

介面也可以進行繼承的動作,同樣也是使用extends關鍵字,例如:
1
2
3
interface 名稱 extends 介面1, 介面2 {
    // ...
}


不同於類別的是,介面可以同時繼承多個介面,這也可以達到多重繼承的功能,而實作子介面的類別必須將所有在父介面和子介面中所定義的方法實做出來。


caterpillar edited on 2005-08-21 19:21
reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-09-13 01:59 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
caterpillar wrote:
1
2
3
4
5
6
7
8
9
10
11
12
class BigServer implements ServerListener {
    private String name;
                                                                                
    public BigServer(String name) {
        this.name = name;
    }
                                                                                
    // 實作介面方法
    public void listen() {
        System.out.println("Now, BigServer " + name + " is listening....");
    }
}


下面這個程式示範一些interface的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
interface ServerListener {
    public void listen();
}
 
class BigServer implements ServerListener {
    private String name;
 
    public BigServer(String name) {
        this.name = name;
    }
 
    // 實作介面方法
    public void listen() {
        System.out.println("Now, BigServer " + name + " is listening....");
    }
}
 
class TinyServer implements ServerListener {
    private String name;
                                                                                
    public TinyServer(String name) {
        this.name = name;
    }
                   
    // 實作介面方法                                                             
    public void listen() {
        System.out.println("Now, TinyServer " + name + " is listening....");
    }
}
 
public class UseInterface {
    public static void main(String[] args) {
        BigServer bigServer = new BigServer("Big Brother");
        TinyServer tinyServer = new TinyServer("Small Boy");
 
        bigServer.listen();
        tinyServer.listen();
    }
}



我強調過兩次了,這樣子的寫法和 interface 扯不上關係(請參閱 J2SE 敝人的貼文: Interface VS Abstract class),bigServer/tinyServer 可以執行 listen 操作並不是因為兩者所屬的 class 有 implements ServerListener,而是二者皆有定義 listene 這個介面。以上述的例子來說,ServerListener 完全沒有存在的必要。下一例子才有點出 interface 的意涵,也才有所謂的 polymorphism。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
zrjian





發文: 80
積分: 0
於 2003-10-22 09:44 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
你好
本身對interface即存有一些疑問,在拜讀本文後,有個問題想請教:
文章中提到:
介面也可以用於宣告型態變數,實作介面的物件可以指定給該變數,一個例子如下所示(本部份最後程式碼):
1
2
3
4
5
6
7
8
public class UseInterface {
    public static void main(String[] args) {
            ServerListener serverListener = new BigServer("Big Brother");
            serverListener.listen();
            serverListener = new TinyServer("Small Boy");
            serverListener.listen();
  }
}

我的困擾問題是:
一個 interface 僅提共別人實作,在程式中如何能像 class 一樣那來運用呢?雖然一個 class 實作了interface ,
但最後還是一個class,如何能將class指定給interface呢?

如上述程式碼
1
ServerListener serverListener = new BigServer("Big Brother");

此時 serverListener(ServerListener是一個interface) 就可像 class 一樣的拿來使用.為何可以如此使用呢?

在java.sql.*中也有類似作法,我的作法是直接使用了,並沒有真正瞭解其意,如
1
2
Connection myCon=null;
myCon = DriverManager.getConnection(url,username,password);

(其中 Connection 也是一個interface)

thanks!


reply to postreply to post
作者 Re:給新手 - 介面(interface) [Re:zrjian]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-10-22 15:54 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
zrjian wrote:
你好
本身對interface即存有一些疑問,在拜讀本文後,有個問題想請教:
文章中提到:
介面也可以用於宣告型態變數,實作介面的物件可以指定給該變數,一個例子如下所示(本部份最後程式碼):


這個問題請參考Duncan的回覆。。。。

就如您可以用父類別的觀點來考慮子類別的操作。

這句話是之前我修課時抄來的。。。。介面的道理也是類似。。。。


reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-10-24 14:28 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
關於interface在使用上的觀念,在The Unified Modeling Language User Guide一書的第十一章中,有許多相當不錯的闡釋。

這本書相當的不錯,UML的三位發起人Grady Booch、James Rumbaugh、Ivar Jacobson所撰寫,我記得好像也有中文書的樣子。

interface在國內翻作介面,在大陸翻作「接口」,後者反而比較能貼近interface的觀念之一:用以作為系統的接合。


reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-10-24 16:14 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
caterpillar wrote:
interface在國內翻作介面,在大陸翻作「接口」,後者反而比較能貼近interface的觀念之一:用以作為系統的接合。


我覺得翻成『介面』也不錯啊,只是比較抽象一點,『接口』比較白話一點罷了。反而我覺得對岸把 port 翻成 『端口』和 interface 的『接口』在意思上我分辨不大清楚。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
TAHO

可愛吧∼∼

版主

發文: 271
積分: 7
於 2004-01-07 04:13 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
現在才回應好像有點晚∼∼@@

我覺得 zrjian 會搞混的原因是因為對於『類別 / 介面』『物件』『變數』『參考(reference)』的分別不夠清晰的原因

類別 / 介面 是一個藍圖,一種規格分類
物件是一個活生生的東西
變數是為了稱呼方便所取的名稱
參考則是一串代表記憶體位置的數字

貓(類別),會握手(介面),你家養的那隻貓(物件),歪歪(變數), E121度23' N22度40' (參考)

貓 (類別) -- 只是一個概念,一種規格,只要符合這種規格的都是貓

你家養的那隻貓(物件) -- 獨一無二,不管天下有多少隻貓,他是獨一無二的
他出生那一刻是貓,一直到死是貓,你把他抓去整形,他也不會中途變成狗
你可以說他是一種脊椎動物,你可以說他是一種哺乳動物,你可以說他是一種生物,但是改變不了他本質是貓的事實

歪歪 -- 天底下叫歪歪的可以有無限多隻,叫歪歪的不一定就是貓,你家那隻貓也不一定要叫歪歪,這只是為了大家談論方便,取的一個名字而已

會握手 -- 很多東西都會握手,不一定是生物,也可能是機器人,這是指支援某種功能

經緯度 -- 這就不用說了,代表的是所在位置,在 C++ 中,你可以藉由加減這個數值得到在這隻貓附近的其它東西的位置
但是 Java 中並不允許你這麼做,你無法對這東西運算

ServerListener serverListener = new BigServer("Big Brother");

雖然短短的一個敘述,但是卻代表了很多觀念
ServerListener serverListener ===> 以下提到的歪歪,是指一個會敬禮的東西
new BigServer() ===> 產生一隻會敬禮的貓,也就是你家養的那隻貓,這是獨一無二的,就算在產生一隻,也不是原來的貓
= 運算子 ===> 把你家養的那隻貓取名做歪歪 ( 讓小喵這個名字跟貓所在的經緯度產生連結)

這時候,雖然你指明,歪歪指的是一個會敬禮的東西,卻不能改變他指向的是一隻貓的事實
serverListener 是一個 ServerListener 介面的變數,但是他存放的參考卻是指向一個 BigServer 類別的實體

嚴格來說:
實際上並沒有 ServerListener 『這個介面』的物件,只有『實作了這個介面的類別』的物件
serverListener 也不是物件,他是一個型別為 ServerListener 的變數,並存放了一個指向 BigServer 物件的參考


TAHO edited on 2004-01-07 04:17
reply to postreply to post
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
slin_2008





發文: 3
積分: 0
於 2006-02-08 17:13 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
开始还有点头绪,但看完-THHO-的后,就全乱了。

reply to postreply to post
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
kentsl





發文: 7
積分: 0
於 2006-02-09 11:20 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
不會ㄚ-THHO-解釋的還不錯呢

具體的舉例更加幫助學習唷


reply to postreply to post
作者 Re:給新手 - 介面(interface) [Re:kentsl]
cozybreeze





發文: 39
積分: 0
於 2006-03-08 10:14 user profilesend a private message to usersend email to cozybreezereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
kentsl wrote:
不會ㄚ-THHO-解釋的還不錯呢

具體的舉例更加幫助學習唷


很多人對比喻的方式並不一定能接受,所以前面大大才會說有點亂了,這是我實際教人東西時發現的,不然哪有所謂的'因材施教'勒,不過看得懂的人會給TAHO豎起大拇指吧Wink

簡單的說 ServerListner 只是要註明製造了一個像BigServer這樣的東西,我要他的臨時用途是ServerListner,所以如果想知道這個東西外型是什麼樣,就會看到BigServer所定義的東東,如果想知道這個東西在這個時機上有什麼臨時用途,那就會看到ServerListener所定義的東東


reply to postreply to post
Java像天使、JavaScript卻像魔鬼=.=
作者 Re:給新手 - 介面(interface) [Re:caterpillar]
瑤瑤





發文: 1
積分: 0
於 2007-01-14 11:17 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
interface 中的成員變數預設是 final 和 static為常數的特徵,不能在其他的程式中修改常數值...

reply to postreply to post
» JWorld@TW »  Java 新手區 » Object/物件導向

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8