java中的接口和抽象類區(qū)別
首先,我們來看一下抽象類的概念,java編程思想中說“萬物皆對象”,我們知道所有的對象都是通過類來描繪的,但是反過來卻不是這樣。并不是所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。抽象類是表征我們對問題領(lǐng)域進行分析、設(shè)計中得出的抽象概念,是對一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象。好比,我們都知道三角形是一個形狀,世界上有三角形這樣具體的東西,但是確沒有形狀這樣具體的東西,我們要描述這個形狀的概念就要用到抽象類。因此在java中抽象類是不允許被實例化的。
在面向?qū)ο箢I(lǐng)域,抽象類主要用來進行類型隱藏。那什么是類型隱藏呢?我們可以構(gòu)造出一個固定的一組行為的抽象描述,但是這組行為卻能夠有任意個可能的具體實現(xiàn)方式。這個抽象描述就是抽象類,而這一組任意個可能的具體實現(xiàn)則表現(xiàn)為所有可能的派生類。好比,動物是一個抽象類,人、猴子、老虎就是具體實現(xiàn)的派生類,我們就可以用動物類型來隱藏人、猴子和老虎的類型。
再來看一下接口,接口是什么呢?Java中的接口是一系列方法的聲明,是一些方法特征的集合,一個接口只有方法的特征沒有方法的實現(xiàn),因此這些方法可以在不同的地方被不同的類實現(xiàn),而這些實現(xiàn)可以具有不同的行為(功能)。接口是一種特殊形式的抽象類。
抽象類和接口有很大的區(qū)別,首先,抽象類在Java語言中表示的是一種繼承關(guān)系,一個類只能使用一次繼承關(guān)系。但是,一個類卻可以實現(xiàn)多個接口。也許,這是Java語言的設(shè)計者在考慮Java對于多重繼承的支持方面的一種折中考慮吧。
其次,在抽象類的定義中,我們可以賦予方法的默認(rèn)行為。但是在接口的定義中,方法卻不能擁有默認(rèn)行為,為了繞過這個限制,必須使用委托,但是這會 增加一些復(fù)雜性,有時會造成很大的麻煩。
已經(jīng)提到過,抽象類在Java語言中體現(xiàn)了一種繼承關(guān)系,要想使得繼承關(guān)系合理,父類和派生類之間必須存在”is a”關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對于接口來說則不然,并不要求接口的實現(xiàn)者和接口定義在概念本質(zhì)上是一致的,僅僅是實現(xiàn)了接口定義的契約而已。接口表示的是”like a”關(guān)系。
使用抽象類來定義允許多個實現(xiàn)的類型,比使用接口有一個明顯的優(yōu)勢:抽象類的演化比接口的演化要容易的多。在后續(xù)的發(fā)行版中,如果希望在抽象類中增加一個方法,只增加一個默認(rèn)的合理的實現(xiàn)即可,抽象類的所有實現(xiàn)都自動提供了這個新的方法。對于接口,這是行不通的。雖然可以在骨架實現(xiàn)類中增加一方法的實現(xiàn)來解決部分問題,但這不能解決不從骨架實現(xiàn)類繼承的接口實現(xiàn)的問題。由此,設(shè)計公有的接口要非常謹(jǐn)慎,一旦一個接口被公開且被廣泛實現(xiàn),對它進行修改將是不可能的。
所以,使用接口還是抽象類,取決于我們對問題的概念的本質(zhì)理解和設(shè)計的意圖。
//---------------------------------------------------------------------
類描述了一個實體,包括實體的狀態(tài),也包括實體可能發(fā)出的動作。
接口定義了一個實體可能發(fā)出的動作。但是只是定義了這些動作的原型,沒有實現(xiàn),也沒有任何狀態(tài)信息。
所以接口有點象一個規(guī)范、一個協(xié)議,是一個抽象的概念;而類則是實現(xiàn)了這個協(xié)議,滿足了這個規(guī)范的具體實體,是一個具體的概念。
從程序角度,簡單理解,接口就是函數(shù)聲明,類就是函數(shù)實現(xiàn)。需要注意的是同一個聲明可能有很多種實現(xiàn)。
1、接口中定義類方法的原型,但是不能說是空方法,因為空方法的意思是有實現(xiàn)體,只不過實現(xiàn)體是空操作。實際上接口沒有定義任何實現(xiàn)體。具體的實現(xiàn)體都是在實現(xiàn)接口的類中,接口只是定義了這些方法的調(diào)用方式。
你當(dāng)然也可以不用接口,直接在類里面寫方法,但是如果你的一組方法需要在很多類里實現(xiàn),那么把它們抽象出來,做成一個接口規(guī)范,不是更好么?
2、一個類描述了一個實體,這個實體可能是一個復(fù)雜的對象,它的動作很多,如果把這些動作分類,用接口a定義其中的某一組動作,接口b定義其中的另外一組動作,這樣的結(jié)構(gòu),比較清楚。
這種方式具備了多繼承的優(yōu)點,避免了多繼承的缺陷。實際上在歷史上,接口在很大程度上,是為了解決多繼承帶來的種種問題而設(shè)計出來的。
3、包中那些已定義的接口,怎么知道那里面定義了什么方法。
接口里定義了方法的輸入輸出,這些都是協(xié)議,具體的實現(xiàn)都在每個類中。對于很多只需要抽象接口的地方,不需要知道具體的類是什么,只要這個類實現(xiàn)了這個接口就可以了。
當(dāng)然,以上只是對接口的初步認(rèn)識,在對面向?qū)ο蟪绦蛟O(shè)計有更深入的認(rèn)識以后,會發(fā)現(xiàn)接口有更廣泛的用途。
另外,抽象類不能被實例化,也就是說,不能創(chuàng)建抽象類的任何對象。必須創(chuàng)建抽象類的子類,然后再創(chuàng)建子類的對象。一個接口可以繼承多個接口,一個類可以實現(xiàn)多個接口。
posted on 2009-08-26 23:06 肥仔 閱讀(436) 評論(0) 編輯 收藏 引用 所屬分類: Web-后臺