国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Java 接口(interface)的作用與好處

2019-11-14 08:44:57
字體:
供稿:網(wǎng)友

首先提出兩個問題:

一、明明可以在類中直接寫所需的方法,為什么還要多寫一個接口(或抽象類)?二、抽象類和接口都差不多,在什么時候才選擇使用接口?

一、抽象類 為了多態(tài)的實(shí)現(xiàn)

假設(shè)現(xiàn)在有7個類,分別如下: 1. 動物(Animal)抽象類 2. 哺乳動物(Mammal)抽象類 繼承動物類 3. 爬行動物(Reptile)抽象類 繼承動物類 4. 老虎(Tiger) 繼承爬行動物類 5. 蛇類(Snake) 繼承爬行動物類 6. 兔子(Rabbit) 繼承哺乳動物類 7. 農(nóng)夫(Farmer)農(nóng)夫可以喂養(yǎng)Animal

1. Animal類

動物都會行走,喝水,代碼如下

abstract class Animal{ public abstract void move(); public abstract void drink();}

2. Mammal類

abstract class Mammal extends Animal{ //繼承動物類的兩個抽象方法,該類為抽象類,不用具體實(shí)現(xiàn)}

3. Raptile類

abstract class Raptile extends Animal{ //繼承動物類的兩個抽象方法,該類為抽象類,不用具體實(shí)現(xiàn)}

4. Tiger類

public class Tiger extends Mammal{ PRivate static String name = "Tiger"; public String getName(){ return this.name; } public void move(){ System.out.println("Tiger moved to " + destination + "."); } public void drink(){ System.out.println("Tiger down to drink water"); }}

5. Snake類

public class Snake extends Raptile{ private static String name = "Snake"; public String getName(){ return this.name; } public void move(){ System.out.println("Snake moved to " + destination + "."); } public void drink(){ System.out.println("Snake stretched his tongue to drink water"); }}

6. Rabbit類

public class Rabbit extends Mammal{ private static String name = "Rabbit"; public String getName(){ return this.name; } public void move(){ System.out.println("Rabbit moved to " + destination + "."); } public void drink(){ System.out.println("Rabbit put out it's tongue and drink."); }}

7. Farmer類

農(nóng)夫沒有繼承任何類,但農(nóng)夫可以給動物喂水喝,而不關(guān)心給什么動物喂水喝,也不關(guān)心動物們從哪里來。

public class farmer{ public void bringWater(String destination){ System.out.println("Farmer bring water to " + destination +"."); } public void feedWater(Animal animal, String destination){ this.bringWater(destination); animal.move(destination); animal.drink(); }}

農(nóng)夫依次去三個地方給三只動物喂水,執(zhí)行Farmer喂水代碼

public void f(){ Tiger tiger = new Tiger(); Snake snake = new Snake(); Rabbit rabbit = new Rabbit(); Farmer farmer = new Farmer(); farmer.feedWater(tiger, room); farmer.feedWater(snake, grassland); farmer.feedWater(rabbit, kichen);}

執(zhí)行結(jié)果:

[java] Farmer bring water to room. [java] Tiger moved to room. [java] Tiger down to drink water. [java] Farmer bring water to grassland. [java] Snake moved to grassland. [java] Snake stretched his tongue to drink water. [java] Farmer bring water to kichen. [java] Rabbit moved to kichen. [java] Rabbit put out it's tongue and drink.

如果老虎、蛇、兔子沒有繼承抽象類來重寫同一個抽象方法,多態(tài)就不能實(shí)現(xiàn) 這樣的話,農(nóng)夫類就要根據(jù)參數(shù)類型重載多個feedwater()方法,像這樣:

feedwater(Tiger tiger, String destination);feedwater(Snake snake, String destination);...

Tiger、Snake、Rabbit繼承了Raptile、Mammer抽象類,而Raptile、Mammer類繼承基類Animal抽象類,所以Tiger、Snake、Rabbit都向上轉(zhuǎn)型為Animal類,例如可以把農(nóng)夫喂水的執(zhí)行代碼寫成下面這樣:

public void f(){ Animal tiger = new Tiger(); Animal snake = new Snake(); Animal rabbit = new Rabbit(); Farmer farmer = new Farmer(); farmer.feedWater(tiger, room); farmer.feedWater(snake, grassland); farmer.feedWater(rabbit, kichen);}

既然抽象類與接口都能實(shí)現(xiàn)多態(tài),那什么時候才需要使用接口呢?

二 、接口的使用

假設(shè)現(xiàn)在農(nóng)夫?qū)W會了一個新方法,帶動物讓Tiger和Snake捕食,需要給Tiger、Snake加一個捕食方法hunt(),Rabbit則不需要此方法。 但從以上類中發(fā)現(xiàn),Snake、Tiger繼承于Raptile、Mammer抽象類,Mammer的子類中有Rabbit類,則hunt()方法不能直接寫入Animal類中,因?yàn)閷懺贏nimal類中,Animal的所有方法將會直接繼承到子類中,由于Rabbit類用不上hunt()方法,則會造成資源浪費(fèi)。 現(xiàn)在考慮幾種方案: 1. 直接將hunt()方法寫在各肉食動物的類中         若這樣做,就不能實(shí)現(xiàn)多態(tài),每個類中的hunt()方法只能由類對象進(jìn)行調(diào)用,像這樣:

Tiger tiger = new Tiger();tiger.hunt(animal);Snake snake = new Snake();snake.hunt(animal);

        此時農(nóng)夫類像這樣,需要對Tiger、Snake類方法重載:

class Farmer{ public void bringWater(String destination){ System.out.println("Farmer bring water to " + destination + "."); } public void bringAnimal(Animal a,String destination){ System.out.println("Farmer bring " + a.getName() + " to " + destination + "."); } public void feedWater(Animal animal, String destination){ this.bringWater(destination); animal.move(destination); animal.drink(); } public void feedAnimal(Tiger tiger , Animal animal){ this.bringAnimal(animal,"Feeding Room"); tiger.move("Feeding Room"); tiger.hunt(animal); } public void feedAnimal(Snake snake, Animal animal){ snake.bringAnimal(animal,"Feeding Room"); snake.move("Feeding Room"); snake.hunt(animal); } }

        若有很多會捕食的動物,將需要大量重載,所以這個方案不可以取。 2. 增加 肉食動物 抽象類         如果是加入肉食動物類與非肉食動物類,將會使得類族圖復(fù)雜化,因?yàn)槿馐硠游镏幸灿胁粫东C的動物。

這個時候就需要用到接口了。

1. Hunt接口

interface Hunt{ public void hunt(Animal animal);}

定義好了接口之后,直接由Tiger、Snake遵循這個接口,需要用到implements關(guān)鍵字:

2. Tiger類

public class Tiger extends Mammal implements Hunt{ private static String name = "Tiger"; public String getName(){ return this.name; } public void move(){ System.out.println("Tiger moved to " + destination + "."); } public void drink(){ System.out.println("Tiger down to drink water"); } public void hunt(Animal animal){ System.out.println("Tiger catched a " + animal.getName() + "and eated it." ) }}

3. Snake類

public class Snake extends Raptile implements Hunt{ private static String name = "Snake"; public String getName(){ return this.name; } public void move(){ System.out.println("Snake moved to " + destination + "."); } public void drink(){ System.out.println("Snake stretched his tongue to drink water"); } public void hunt(Animal animal){ System.out.println("Tiger catched a " + animal.getName() + "and eated it." ) }}

4. Farmer類

public class farmer{ public void bringWater(String destination){ System.out.println("Farmer bring water to " + destination + "."); } public void bringAnimal(Animal a,String destination){ System.out.println("Farmer bring " + a.getName() + " to " + destination + "."); } public void feedWater(Animal animal, String destination){ this.bringWater(destination); animal.move(destination); animal.drink(); } public void feedAnimal(Hunt hunter, Animal animal){ this.bringAnimal(animal,"Feeding Room"); Animal ht = (Animal)hunter; ht.move("Feeding Room"); hunter.hunt(animal); }}

此時接口實(shí)現(xiàn)了多態(tài)。 接口也成為Java中的多重繼承,在導(dǎo)出類中,如果是從一個非接口的類繼承,那只能繼承這一個類,其余的基元素都必須是接口,需要把所有的接口都置于implements關(guān)鍵字之后,用逗號將它們隔開。

現(xiàn)在總結(jié)一下文章一開始提出的兩個問題

一、明明可以在類中直接寫所需的方法,為什么還要多寫一個接口(或抽象類)?        1. 減少代碼的書寫(上邊分析的代碼重載)        2. 提高了代碼的可維護(hù)性和擴(kuò)展性。        3. 在團(tuán)隊(duì)合作中,代碼的規(guī)范性

二、抽象類和接口都差不多,在什么時候才選擇使用接口?        1. 在當(dāng)前類族中不是必須的(例如Tuger需要而Rabbit不需要)的方法時        2. 不同類族的多個類需要實(shí)現(xiàn)同樣的方法時(接口)

接口還有許多沒有總結(jié)的特點(diǎn),例如泛型接口,總之學(xué)會規(guī)范使用接口,就會在將來的項(xiàng)目中,有著很大的幫助。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 香格里拉县| 永定县| 保德县| 吕梁市| 福清市| 库伦旗| 温泉县| 潢川县| 泗阳县| 宜黄县| 白朗县| 文山县| 锡林浩特市| 海晏县| 蓬溪县| 崇义县| 大关县| 偃师市| 双牌县| 肃宁县| 荔波县| 筠连县| 定陶县| 三江| 莱西市| 武山县| 潞西市| 永清县| 大田县| 东莞市| 蕲春县| 新乡市| 鱼台县| 黄冈市| 固安县| 海宁市| 尼玛县| 晴隆县| 萍乡市| 巢湖市| 株洲县|