類(lèi)是對(duì)象的模板,抽象類(lèi)和接口可以看做是具體的類(lèi)的模板均牢。
由于從某種角度講糠雨,接口是一種特殊的抽象類(lèi),它們的淵源頗深徘跪,有很大的相似之處甘邀,所以在選擇使用誰(shuí)的問(wèn)題上很容易迷糊。我們首先分析它們具有的相同點(diǎn)垮庐。
都代表類(lèi)樹(shù)形結(jié)構(gòu)的抽象層鹃答。在使用引用變量時(shí),盡量使用類(lèi)結(jié)構(gòu)的抽象層突硝,使方法的定義和實(shí)現(xiàn)分離测摔,這樣做對(duì)于代碼有松散耦合的好處。
都不能被實(shí)例化解恰。
都能包含抽象方法锋八。抽象方法用來(lái)描述系統(tǒng)提供哪些功能,而不必關(guān)心具體的實(shí)現(xiàn)护盈。
下面說(shuō)一下抽象類(lèi)和接口的主要區(qū)別挟纱。
- 抽象類(lèi)可以為部分方法提供實(shí)現(xiàn),避免了在子類(lèi)中重復(fù)實(shí)現(xiàn)這些方法腐宋,提高了代碼的可重用性紊服,這是抽象類(lèi)的優(yōu)勢(shì)檀轨;而接口中只能包含抽象方法,不能包含任何實(shí)現(xiàn)欺嗤。
public abstract class A{
public abstract void method1();
public void method2(){
//A method2
}
}
public class B extends A{
public void method1(){
//B method1
}
}
public class C extends A{
public void method1(){
//C method1
}
}
抽象類(lèi)A有兩個(gè)子類(lèi)B参萄、C,由于A中有方法method2的實(shí)現(xiàn)煎饼,子類(lèi)B讹挎、C中不需要重寫(xiě)method2方法,我們就說(shuō)A為子類(lèi)提供了公共的功能吆玖,或A約束了子類(lèi)的行為筒溃。method2就是代碼可重用的例子。A 并沒(méi)有定義 method1的實(shí)現(xiàn)沾乘,也就是說(shuō)B怜奖、C 可以根據(jù)自己的特點(diǎn)實(shí)現(xiàn)method1方法,這又體現(xiàn)了松散耦合的特性翅阵。
再換成接口看看:
public interface A{
public void method1();
public void method2();
}
public class B implements A{
public void method1(){
//B method1
}
public void method2(){
//B method2
}
}
public class C implements A{
public void method1(){
//C method1
}
public void method2(){
//C method2
}
}
接口A無(wú)法為實(shí)現(xiàn)類(lèi)B歪玲、C提供公共的功能,也就是說(shuō)A無(wú)法約束B(niǎo)怎顾、C的行為。B漱贱、C可以自由地發(fā)揮自己的特點(diǎn)現(xiàn)實(shí) method1和 method2方法槐雾,接口A毫無(wú)掌控能力。
- 一個(gè)類(lèi)只能繼承一個(gè)直接的父類(lèi)(可能是抽象類(lèi))幅狮,但一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口募强,這個(gè)就是接口的優(yōu)勢(shì)。
interface A{
public void method2();
}
interface B{
public void method1();
}
class C implements A,B{
public void method1(){
//C method1
}
public void method2(){
//C method2
}
}
//可以如此靈活的使用C崇摄,并且C還有機(jī)會(huì)進(jìn)行擴(kuò)展擎值,實(shí)現(xiàn)其他接口
A a=new C();
B b=new C();
abstract class A{
public abstract void method1();
}
abstract class B extends A{
public abstract void method2();
}
class C extends B{
public void method1(){
//C method1
}
public void method2() {
//C method2
}
}
對(duì)于C類(lèi),將沒(méi)有機(jī)會(huì)繼承其他父類(lèi)了逐抑。
綜上所述鸠儿,接口和抽象類(lèi)各有優(yōu)缺點(diǎn),在接口和抽象類(lèi)的選擇上厕氨,必須遵守這樣一個(gè)原則:
行為模型應(yīng)該總是通過(guò)接口而不是抽象類(lèi)定義进每,所以通常是優(yōu)先選用接口,盡量少用抽象類(lèi)命斧。
選擇抽象類(lèi)的時(shí)候通常是如下情況:需要定義子類(lèi)的行為田晚,又要為子類(lèi)提供通用的功能。
如果你現(xiàn)在也在學(xué)習(xí)java国葬,在入門(mén)學(xué)習(xí)java的過(guò)程當(dāng)中缺乏系統(tǒng)的學(xué)習(xí)教程贤徒,或者說(shuō)缺乏一個(gè)交流技術(shù)的地方芹壕,你可以申請(qǐng)加入我的Java學(xué)習(xí)交流qun:六四一,一二一接奈,九四八踢涌。里面還有我這幾年整理的java學(xué)習(xí)手冊(cè),面試題鲫趁,開(kāi)發(fā)工具斯嚎,PDF文檔教程,你可以自行去下載挨厚。