Java基礎(chǔ)知識(shí)之接口和抽象類的區(qū)別
1.接口
??接口是抽象方法的集合,一個(gè)接口只有方法的形狀而沒有方法的具體實(shí)現(xiàn),接口是Java面向?qū)ο筇峁┑囊环N機(jī)制。
??Java語言是一種單繼承的猎唁,在類的繼承中通過實(shí)現(xiàn)多個(gè)接口間接實(shí)現(xiàn)了多繼承功能。接口的申明:
[public] interface InterfaceName{
void method1(int arg1);
void method2();
...
}
2.抽象類
??抽象類是用來捕捉子類的通用特性的 顷蟆。它不能被實(shí)例化,只能被用作子類的超類腐魂。抽象類是被用來創(chuàng)建繼承層級(jí)里子類的模板帐偎。抽象類申明:
[public] abstract class ClassName {
abstract void fun();
void fun2();
...
}
3.接口和抽象類區(qū)別
??(1)、接口只能包含抽象方法蛔屹,抽象類可以包含普通方法削樊;
??(2)、接口的方法都是完全抽象的兔毒,并且方法必須是public漫贞,而且默認(rèn)方法是public abstract的,抽象中的方法可以被public,protected等修飾符修飾育叁;
??(3)迅脐、子類用implements來實(shí)現(xiàn)接口,子類需要實(shí)現(xiàn)接口中的所有方法豪嗽,但繼承抽象類可以不重寫父類中非抽象方法谴蔑,抽象類中的抽象方法必須被重寫;
??(4)龟梦、一個(gè)類可以實(shí)現(xiàn)多個(gè)接口隐锭,但只能繼承最多一個(gè)抽象類,接口可以繼承一個(gè)或者多個(gè)接口计贰;
??(5)钦睡、抽象類中可以有普通成員變量,接口中沒有普通成員變量躁倒,只能有常量荞怒;
??(6)、抽象類中的方法可以被static修飾樱溉,接口中的方法不可以被static修飾挣输;
??(7)、抽象類可以有構(gòu)造函數(shù)福贞,接口不可以有構(gòu)造函數(shù)撩嚼。
??PS:相同點(diǎn)是都不能實(shí)例化(不能new),都有抽象方法,子類中必須對(duì)父類方法進(jìn)行重寫完丽。
4.接口和抽象類的使用場(chǎng)景
??接口主要用于實(shí)現(xiàn)多繼承的場(chǎng)景和模塊與模塊之間的調(diào)用情況恋技,抽象類主要用于當(dāng)做基礎(chǔ)類使用,即基類(基類里面的一些方法都有默認(rèn)的方法實(shí)現(xiàn)逻族,即實(shí)現(xiàn)接口的公用的代碼蜻底,個(gè)性化的方法由各個(gè)子類去實(shí)現(xiàn))。
5.Demo
??下面看一個(gè)網(wǎng)上流傳最廣泛的例子:門和警報(bào)的例子:門都有open( )和close( )兩個(gè)動(dòng)作:
??抽象類定義:
abstract class Door {
public abstract void open();
public abstract void close();
}
??或者接口定義如下:
interface Door {
void open();
void close();
}
??但是現(xiàn)在如果我們需要門具有報(bào)警alarm( )的功能聘鳞,那么該如何實(shí)現(xiàn)薄辅?下面提供兩種思路:
??1)將這三個(gè)功能都放在抽象類里面,但是這樣一來所有繼承于這個(gè)抽象類的子類都具備了報(bào)警功能抠璃,但是有的門并不一定具備報(bào)警功能站楚;
??2)將這三個(gè)功能都放在接口里面,需要用到報(bào)警功能的類就需要實(shí)現(xiàn)這個(gè)接口中的open( )和close()搏嗡,也許這個(gè)類根本就不具備open( )和close()這兩個(gè)功能窿春,比如火災(zāi)報(bào)警器。
??從這里可以看出采盒, Door的open() 旧乞、close()和alarm()根本就屬于兩個(gè)不同范疇內(nèi)的行為,open()和close()屬于門本身固有的行為特性磅氨,而alarm()屬于延伸的附加行為尺栖。因此最好的解決辦法是單獨(dú)將報(bào)警設(shè)計(jì)為一個(gè)接口,包含alarm()行為,Door設(shè)計(jì)為單獨(dú)的一個(gè)抽象類悍赢,包含open和close兩種行為决瞳。再設(shè)計(jì)一個(gè)報(bào)警門繼承Door類和實(shí)現(xiàn)Alarm接口。最終的方案源碼如下:
abstract class Door{
void open();
void close();
}
interface Alarm {
void alarm();
}
public class AlarmDoor extends Door implements Alarm {
void open() {
...
}
void close() {
...
}
void alarm() {
...
}
}