接觸Java已經(jīng)有一段時(shí)間了贡翘,接口和抽象類也到處在用,用著用著就習(xí)慣了砰逻,也沒(méi)去想接口和抽象類到底應(yīng)該怎么用鸣驱。
什么是接口,什么是抽象類蝠咆,不需要Google踊东,連百度都一大堆。什么是接口刚操?
其實(shí)這些書(shū)上都講過(guò)闸翅,可能也都舉過(guò)例子。但是就我自己來(lái)說(shuō)菊霜,我看完教科書(shū)對(duì)接口的描述坚冀,并不是很懂,雖然我很清楚怎么用鉴逞,甚至用的很好记某,卻就是不知道怎么描述司训。
我為什么突然想要去了解他,而不是反正我現(xiàn)在用的好好的液南,只要會(huì)用就行了壳猜。我記得我當(dāng)時(shí)在看設(shè)計(jì)模式,工廠方法和抽象工廠贺拣,對(duì)于接口突然產(chǎn)生了疑問(wèn)蓖谢,當(dāng)時(shí)我舉了一個(gè)這樣的例子(第一種寫(xiě)法)
interface Food {
}
interface Cook {
Food cook();
}
廚師可以做出食物,廚師和食物都是接口
class Dumpling implements Food {
}
class ChineseFoodChef implements Cook {
@Override
public Food cook() {
return new Dumpling();
}
}
中國(guó)廚師做餃子譬涡,并沒(méi)有什么錯(cuò)闪幽,跑的好好的。但是有沒(méi)有覺(jué)得涡匀,Cook和Food其實(shí)作為抽象類更符合邏輯一點(diǎn)盯腌,所以我這樣寫(xiě),直接用抽象類(第二種寫(xiě)法)
abstract class Food {
}
class Dumpling extends Food {
}
abstract class Cook{
public abstract Food cook();
}
class ChineseFoodChef extends Cook {
@Override
public Food cook() {
return new Dumpling();
}
}
或者下面這種(第三種寫(xiě)法)
interface Eatable {
}
abstract class Food implements Eatable{
}
class Dumpling extends Food {
}
interface CanCook {
Eatable cook();
//Food cook();
}
abstract class Cook implements CanCook{
public abstract Food cook();
}
class ChineseFoodChef extends Cook {
@Override
public Food cook() {
return new Dumpling();
}
}
這樣是不是符合邏輯多了陨瘩,但是代碼也變多了腕够。然后接下來(lái)需求變了,多了一類人舌劳,教師帚湘。另外我媽媽是教師,并且會(huì)做菜甚淡。說(shuō)簡(jiǎn)單一點(diǎn)就是大诸,我媽媽是一個(gè)會(huì)做飯的教師。所以按照第一種寫(xiě)法
interface Teacher {
void teach();
}
class MyMonther implements Teacher,Cook {
@Override
public void teach() {
}
@Override
public Food cook() {
return null;
}
}
感覺(jué)上表達(dá)出來(lái)的意思是贯卦,我媽媽是一個(gè)教師也是一個(gè)廚師资柔,或者我媽媽會(huì)教書(shū)也會(huì)做菜,也并沒(méi)有什么錯(cuò)撵割。然后第二種寫(xiě)法
abstract class Teacher{
public abstract void teach();
}
class MyMonther extends Teacher {
@Override
public void teach() {
}
public Food cook() {
return null;
}
}
因?yàn)椴荒芾^承兩個(gè)父類贿堰,所以只能自己另外加一個(gè)方法。然后第三種寫(xiě)法
interface CanTeach {
void teach();
}
abstract class Teacher implements CanTeach {
}
class MyMonther extends Teacher implements CanCook{
@Override
public void teach() {
}
@Override
public Food cook() {
return null;
}
}
第三種是不是更符合要表達(dá)的意思啡彬,我媽媽是一個(gè)會(huì)做菜的教師羹与。不過(guò)對(duì)于上面的題材三種寫(xiě)法都可以,現(xiàn)在用下面這些(鳥(niǎo)庶灿,鴕鳥(niǎo)注簿,麻雀,飛機(jī)跳仿,會(huì)飛的)
interface 鳥(niǎo) {
void 飛();
}
class 鴕鳥(niǎo) implements 鳥(niǎo) {
@Override
public void 飛() {
}
}
class 麻雀 implements 鳥(niǎo) {
@Override
public void 飛() {
}
}
class 飛機(jī) implements 鳥(niǎo) {
@Override
public void 飛() {
}
}
看到這里其實(shí)顯而易見(jiàn)诡渴,用一類事物的抽象名詞作為接口名是很不符合邏輯的,鴕鳥(niǎo)是鳥(niǎo)但不會(huì)飛,飛機(jī)會(huì)飛但不是鳥(niǎo)妄辩。所以其實(shí)這類名詞用抽象類是最符合的
abstract class 鳥(niǎo) {
public abstract void 飛();
}
class 鴕鳥(niǎo) extends 鳥(niǎo) {
@Override
public void 飛() {
}
}
class 麻雀 extends 鳥(niǎo) {
@Override
public void 飛() {
}
}
abstract class 飛機(jī) {
public abstract void 飛();
}
class 波音747 extends 飛機(jī) {
@Override
public void 飛() {
}
}
于是惑灵,鴕鳥(niǎo)還是會(huì)飛?exm眼耀?鳥(niǎo)和飛機(jī)有一樣的方法英支,多寫(xiě)一遍不累么?所以接口的價(jià)值就體現(xiàn)出來(lái)了
interface 會(huì)飛的 {
void 飛();
}
abstract class 鳥(niǎo) {
}
class 鴕鳥(niǎo) extends 鳥(niǎo) {
//鴕鳥(niǎo)是鳥(niǎo)但不會(huì)飛
}
class 麻雀 extends 鳥(niǎo) implements 會(huì)飛的{
@Override
public void 飛() {
}
}
abstract class 飛機(jī) implements 會(huì)飛的{
}
class 波音747 extends 飛機(jī) {
@Override
public void 飛() {
}
}
其實(shí)接口就像一個(gè)可以靈活拆裝的組件哮伟,你想讓豬飛干花,只要給它裝個(gè)會(huì)飛的接口就行了,你想讓你的爸媽會(huì)做飯楞黄,給他們裝個(gè)會(huì)做飯的接口就好了池凄,哈哈哈
以上就是我的理解,不敢說(shuō)不服來(lái)辯鬼廓,如果有好的見(jiàn)解希望可以一起討論肿仑。覺(jué)得多個(gè)例子對(duì)比著來(lái)應(yīng)該比單個(gè)舉例效果要好,最近也在斷斷續(xù)續(xù)的看設(shè)計(jì)模式碎税,也會(huì)寫(xiě)一寫(xiě)自己的理解尤慰,一方面寫(xiě)下來(lái)能讓自己的理解更深刻甚至產(chǎn)生新疑問(wèn),另一方面也是為了能和大神們分享討論(感覺(jué)大神們都應(yīng)該不需要看我這么淺顯的理解=雷蹂。=)