java學習筆記8--接口總結

生活中的接口:

什么是接口?

一個Java接口是一些方法特征的集合,但沒有方法的實現。

在類中實現接口可以使用關鍵字implements,其基本格式如下:

[修飾符] class <類名> [extends 父類名] [implements 接口列表]{
}
修飾符:可選參數,用于指定類的訪問權限,可選值為public、abstract和final。

類名:必選參數,用于指定類的名稱,類名必須是合法的Java標識符。一般情況下,要求首字母大寫。

extends 父類名可選參數,用于指定要定義的類繼承于哪個父類。當使用extends關鍵字時,父類名為必選參數。

implements 接口列表:可選參數,用于指定該類實現的是哪些接口。當使用implements關鍵字時,接口列表為必選參數。當接口列表中存在多個接口名時,各個接口名之間使用逗號分隔。

實現上面例子中的接口:

public interface PCI {  //java接口,相當于主板上的PCI插槽的規范public void start();public void stop();
}

Java接口中定義的方法在不同的地方被實現,可以具有完全不同的行為:

//聲卡、網卡都實現了PCI插槽的規范,但行為完全不同 
class SoundCard implements PCI {    public void start() {System.out.println("SoundCard start...");}public void stop() {System.out.println("Sound stop!");}
}
class NetworkCard implements PCI {public void start() {System.out.println("NetworkCard send...");}public void stop() {System.out.println("Send stop!");}
}

可以使用Java接口標識類型。運行時,根據實際創建的對象類型調用相應的方法實現:

public class javatest {public static void main(String[] args) {PCI nc = new NetworkCard();PCI sc = new SoundCard();nc.start();sc.start();}
}

運行結果:

NetworkCard send...
SoundCard start...

為什么需要Java接口?

例子:為學校各中心開發這樣一個小系統,包含類型:教員、中心、打印機,具體要求如下:

1、教員、以及中心都具有方法:輸出詳細信息

2、中心具有屬性:打印機,能夠通過中心的打印機打印教員或中心的詳細信息

3、系統要具備良好的可擴展性與可維護性

先看方案1:

public class Teacher {//輸出教員的詳細信息public String detail() {return “I am a teacher!";}
}
public class Printer {public void print(String content) {System.out.println("start printing:");              System.out.println(content);}
}
public class ggSchool {private Printer printer = new Printer();//輸出學校的詳細信息public String detail() {return “this is ggSchool";}//使用打印機打印教員信息public void print(Teacher t){printer.print(t.detail());}//使用打印機打印學院信息public void print(ggSchool s){printer.print(s.detail());}
}

那么,問題來了:

每增加一種新類型,都需要增加相應的print方法,程序的可擴展性及可維護性極差,這不符合系統的要求

先看方案2(使用接口):

教師、中心都存在一個共同的方法特征:detail,它們對detail方法有各自不同的實現——這完全符合Java接口的定義

代碼如下:

public interface Introduceable {public String detail();
}
public class Teacher implements Introduceable {//輸出教員的詳細信息public String detail() {return “I am a teacher!";}
}
public class ggSchool implements Introduceable {private Printer printer = new Printer();//輸出學校的詳細信息public String detail() {returnthis is ggSchool";}public void print(Introduceable intro) {    //使用print方法時,參數可以是任何Introduceable接口的實現類的對象,//不必再為不同的類型建立不同的print方法了printer.print(intro.detail());}
}
public class Printer {public void print(String content) {System.out.println("start printing:");              System.out.println(content);}
}

通過Java接口,我們同樣可以享受到多態性的好處,大大提高了程序的可擴展性及可維護性?

什么是面向接口編程?

開發系統時,主體構架使用接口,接口構成系統的骨架,這樣就可以通過更換接口的實現類來更換系統的實現

升級上面的系統,要求:

打印機有多種類型,比如:黑白打印機、彩色打印機等

學院可能配備其中任意一款打印機,負責打印教員、或者學院的詳細信息

系統要具備良好的可擴展性與可維護性

第一步:抽象出Java接口

1、分析:

黑白、彩色打印機都存在一個共同的方法特征:print

黑白、彩色打印機對print方法有各自不同的實現

2、結論:

抽象出Java接口PrinterFace,在其中定義方法print

3、具體實現:

public interface PrinterFace {public void print(String content);
}
第二步:實現Java接口

1、分析:

已經抽象出Java接口PrinterFace,并在其中定義了print方法黑白、彩色打印機對print方法有各自不同的實現

2、結論:黑白、彩色打印機都實現PrinterFace接口,各自實現print方法

3、具體實現:

public class ColorPrinter implements PrinterFace {public void print(String content) {System.out.println("彩色打印:");System.out.println(content);}
}
public class BlackPrinter implements PrinterFace {public void print(String content) {System.out.println("黑白打印:");System.out.println(content);}
}

第三步:使用Java接口

1、分析:主體構架使用接口, 讓接口構成系統的骨架

2、結論:更換實現接口的類就可以更換系統的實現

3、具體實現:

public class ggSchool implements Introduceable{private PrinterFace printer;  //打印機public void setPrinter(PrinterFace p) {this.printer = p;}public String detail() {return "this is ggSchool!";}public void print(Introduceable intro){printer.print(intro.detail());}
}
public class Test {public static void main(String[] args) {// 創建學院實例ggSchool school=new ggSchool();//為該學院配備黑白打印機school.setPrinter(new BlackPrinter());school.print(school); //為該學院配備彩色打印機school.setPrinter(new ColorPrinter());school.print(school);}
}

抽象類與接口

抽象類的子類必須覆蓋所有的抽象方法后才能被實例化,否則這個子類還是個抽象類。

如果一個抽象類中的所有方法都是抽象的,就可以將這個類用另外一種方式來定義,也就是接口定義。

抽象方法只需聲明,不需實現。

接口是抽象方法和常量值的定義的集合。

從本質上講,接口是一種特殊的抽象類。這種抽象類中包含常量和方法的定義,而沒有變量和方法的實現。例如

注意:在接口的定義中,所有的成員都是public訪問類型的,而不論是否用public關鍵字修飾;接口里的變量都是用public static final標識的,所以,接口中定義的變量就是全局靜

態常量。

我們可以定義一個新的接口,用extends關鍵字去繼承一個已有的接口。注意:只能接口繼承接口,類不能繼承接口。

一個類只能用implements關鍵字去實現一個接口中的所有方法

一個類可以在繼承一個父類的同時,實現一個或多個接口,extends關鍵字必須位于implements關鍵字之前,如我們可以這樣定義:

class classA {//...
}
public interface Interface1{//...
}
public interface Interface2{//...
}
class classB extends classA implements Interface1 Interface2{//...
}

抽象類和接口的區別

1.語法層面上的區別

  1)抽象類可以提供成員方法的實現細節,而接口中只能存在public abstract 方法;

  2)抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是public static final類型的;

  3)接口中不能含有靜態代碼塊以及靜態方法,而抽象類可以有靜態代碼塊和靜態方法;

  4)一個類只能繼承一個抽象類,而一個類卻可以實現多個接口。

2.設計層面上的區別

  1)抽象類是對一種事物的抽象,即對類抽象,而接口是對行為的抽象。抽 象類是對整個類整體進行抽象,包括屬性、行為,但是接口卻是對類局部(行為)進行抽象。舉個簡單的例子,飛機和鳥是不同類的事物,但是它們都有一個共性, 就是都會飛。那么在設計的時候,可以將飛機設計為一個類Airplane,將鳥設計為一個類Bird,但是不能將 飛行 這個特性也設計為類,因此它只是一個行為特性,并不是對一類事物的抽象描述。此時可以將 飛行 設計為一個接口Fly,包含方法fly( ),然后Airplane和Bird分別根據自己的需要實現Fly這個接口。然后至于有不同種類的飛機,比如戰斗機、民用飛機等直接繼承Airplane 即可,對于鳥也是類似的,不同種類的鳥直接繼承Bird類即可。從這里可以看出,繼承是一個 "是不是"的關系,而接口實現則是 "有沒有"的關系。如果一個類繼承了某個抽象類,則子類必定是抽象類的種類,而接口實現則是有沒有、具備不具備的關系,比如鳥是否能飛(或者是否具備飛行這個特點),能飛行則可以實現這個接口,不能飛行就不實現這個接口。

  2)設計層面不同,抽象類作為很多子類的父類,它是一種模板式設計。而接口是一種行為規范,它是一種輻射式設計。什 么是模板式設計?最簡單例子,大家都用過ppt里面的模板,如果用模板A設計了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它們的公共部分需要改動,則只需要改動模板A就可以了,不需要重新對ppt B和ppt C進行改動。而輻射式設計,比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更新。也就是說對于抽象類,如果需要添加新的方法,可以直接在抽 象類中添加具體的實現,子類可以不進行變更;而對于接口則不行,如果接口進行了變更,則所有實現這個接口的類都必須進行相應的改動。

下面看一個網上流傳最廣泛的例子:門和警報的例子:門都有open( )和close( )兩個動作,此時我們可以定義通過抽象類和接口來定義這個抽象概念:

abstract class Door {public abstract void open();public abstract void close();
}

或者:

interface Door {public abstract void open();public abstract void close();
}

但是現在如果我們需要門具有報警alarm( )的功能,那么該如何實現?下面提供兩種思路:

1)將這三個功能都放在抽象類里面,但是這樣一來所有繼承于這個抽象類的子類都具備了報警功能,但是有的門并不一定具備報警功能;

2)將這三個功能都放在接口里,需要用到報警功能的類就需要實現這個接口中的open( )和close( ),也許這個類根本就不具備open( )和close( )這兩個功能,比如火災報警器。

從這里可以看出,?Door的open() 、close()和alarm()根本就屬于兩個不同范疇內的行為,open()和close()屬于門本身固有的行為特性,而alarm()屬于延伸的 附加行為。因此最好的解決辦法是單獨將報警設計為一個接口,包含alarm()行為,Door設計為單獨的一個抽象類,包含open和close兩種行 為。再設計一個報警門繼承Door類和實現Alarm接口。

interface Alram {void alarm();
}abstract class Door {void open();void close();
}class AlarmDoor extends Door implements Alarm {void oepn() {//....}void close() {//....}void alarm() {//....}
}

抽象類和接口在Java中的應用

例子:假設有若干 (如1000)個Circle,Rectangle以及若干個其他形狀,希望計算它們的總面積,直截了當的做法是將它們分別放到多個數組中,分別循環求出 各形狀的面積,然后累加,這種做法是不漂亮的。如果還有其它形狀:triangle,ellipses等,上述方法顯得“累贅”。希望有一種統一的表示, 例如用一個數組shape[],接受所有的形狀,然后用:

 for (i=0; i<shape.length; i++)area_total += shape[i].area();

用抽象類實現多種形狀面積的累加:

首先看看Circle和Rectangle兩個類,如何完成相關參數的計算 :

class Circle {public float r; Circle(float r) {this.r = r;      }public float area() {return 3.14 * r * r;}
}
class Rectangle {public float width, height; Rectangle (float w, float h) {width = w; height = h;}public float area() {return width * height;}
}

現在要利用抽象類實現多種形狀面積的累加,確保每種形狀分別用不同的方法來計算它們的面積和周長。因此,超類Shape包含抽象方法 computeArea,然后在不同的子類中實現和覆蓋這個方法,同時添加toString方法來顯示幾何形狀的一些基本屬性。現在聲明了1000個 Shape對象的數組,然后循環1000次隨機產生1000個平面圖形對象,形狀為圓、矩形、正方形三種之一。

abstract class Shape {abstract float computeArea();
}
class Circle extends Shape {public float r;public Circle(float r) {this.r = r;}public float computeArea() {return (float)3.14 * r * r;}
}
class Rectangle extends Shape {public float width, height; Rectangle (float w, float h) {width = w; //這里不需"this"height = h;}public float computeArea() {return width * height;}
}

用接口實現多種形狀面積的累加:

用接口的方式實現多種形狀面積的累加,需要將用抽象類表示的Shape類改成接口。由于接口的語法定義要求,我們要把原來抽象類中的成員變量去掉,成員方法改成抽象方法computeArea(),該方法返回一個double類型。所以,這個接口定義為:

public interface Shape2 {  public abstract double computeArea();
}

接口實現如下:

interface Shape2
{  public double computeArea();
}
class Circle2 implements Shape2
{protected double radius;public Circle2(double _radius) {radius = _radius;}public double computeArea() { return Math.PI * radius * radius; }
}
class Rect2 implements Shape2
{  protected double width, height;public Rect2(double w, double h) {  width = w;height = h;}public double computeArea() {  return width * height; }
}

用一個object數組實現多種形狀面積的累加:

定義一個數組,它可以同時存儲矩形、圓和正方形,每個Java類都是由Object擴展而來的。因此,所有的類都屬于Object類型,我們可以創建一個Object類型的數組來存儲任何類型的對象,也就可以存儲矩形、圓和正方形對象

完整代碼如下:

package javatest;
import java.util.*;
import java.io.*;interface Shape2 {  public double computeArea();
}
class Circle2 implements Shape2 {protected double radius;public Circle2(double _radius) {radius = _radius;}public double computeArea() { return Math.PI * radius * radius; }
}
class Rect2 implements Shape2 {  protected double width, height;public Rect2(double w, double h) {  width = w;height = h;}public double computeArea() {  return width * height; }
}
public class javatest {  public static void main(String args[ ]) { Shape2 s[] = { new Circle2(4),  new Rect2(4, 4), new Circle2(10),  new Rect2(20, 2), new Rect2(8, 10)};double total = 0;for(int i = 0; i < s.length; i++)total = total + s[i].computeArea();System.out.println("totalArea = " + (int)total);}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284975.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284975.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284975.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

.NET自定義認證雖然簡單,但好用

前言有這樣一種場景&#xff0c;就是新項目已經集成了認證中心&#xff0c;或者是都用了統一的認證方式(比如現在常用的JWT)&#xff0c;這樣對于項目之間的對接就顯得比較方便&#xff0c;至少在認證這塊還是能減少一些工作量的。但當上線的老項目需要對接新項目時&#xff0c…

C語言試題187之實現strspn函數功能

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款刷算法、筆試、面經、拿大公司offer神器?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目: 實現st…

一張圖對比騰訊、阿里、百度的薪資職級

作為中國互聯網三大巨頭的騰訊、阿里、百度&#xff0c;他們的職級薪資福利等等等一直都是個謎&#xff0c;不為外界所知。今天&#xff0c;我就來為大家全面揭曉—— Here we go&#xff5e; 公司總部 - 騰訊&#xff1a;總部在深圳南山科技園&#xff0c;CBD地段&#xff1…

旺財速啃H5框架之Bootstrap(五)

在上一篇<<旺財速啃H5框架之Bootstrap&#xff08;四&#xff09;>>做了基本的框架&#xff0c;<<旺財速啃H5框架之Bootstrap&#xff08;二&#xff09;>>篇里也大體認識了bootstrap.css樣式&#xff0c;下面我們來學習常見的CSS操控內容篇幅。。。。…

【專升本計算機】最新甘肅省專升本考試C語言部分復習題帶答案

最新甘肅省專升本考試C語言部分復習題帶答案 考點1.1-1.2 1、 C 語言源程序文件經過 C 編譯器編譯之后生成一個后綴為( )的文件 A. .c B. .obj C. .exe D. .bas 2、 C 語言源程序文件經過 C 編譯器連接之后生成一個后綴為( )的文件 A. .c B. .obj C. .exe D. .bas 3、完成 …

浮點數一些設計原理

摘要&#xff1a;本篇文章會講述浮點數的設計原理&#xff0c;比如如何存儲二進制的問題&#xff0c;從而幫助我們更好的編碼。 __1. deading code __ console.log(1.0-0.9 0.1); //輸出 false console.log(1.0-0.9, 0.1); //輸出 0.09999999999999998 0.1 //所以判斷浮點運算…

Atitit. http 代理原理 ?atiHttpProxy ?大木馬

Atitit. http 代理原理 atiHttpProxy 大木馬 1. 面這張圖可以清晰地闡明HttpProxy的實現原理&#xff1a;1 2. 代理服務器用途1 3. 其中流程具體如下&#xff1a;2 4. 設計規劃3 5. 結束語4 1. 面這張圖可以清晰地闡明HttpProxy的實現原理&#xff1a; 2. 代理服務器用途 代…

[轉]一文揭秘阿里、騰訊、百度的薪資職級

上周&#xff0c;阿里巴巴董事長兼CEO逍遙子發布內部郵件&#xff0c;宣布了阿里巴巴新一輪組織部晉升名單&#xff0c;涉及所有晉升到P10、P11、P12的高P的人員。其中晉升到M7/ P12的高級管理者包括&#xff1a;淘寶、天貓、阿里媽媽事業群總裁蔣凡、阿里本地生活服務公司CEO王…

C語言試題188之實現strcspn函數功能

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款刷算法、筆試、面經、拿大公司offer神器?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目: 實現st…

【ArcGIS微課1000例】0014:ArcGIS中如何將kml(kmz)文件轉shp,并進行投影轉換?

KML(Keyhole Markup Language,Keyhole 標記語言)最初是由Google 旗下的Keyhole 公司開發和維護的一種基于XML 的標記語言,利用XML 語法格式描述地理空間數據(如點、線、面、多邊形和模型等),適合網絡環境下的地理信息協作與共享。2008 年4月,KML的最新版本2.2 被OGC 宣布為開…

寫一鍵部署bash腳本

因為我開源的一鍵部署應用到linux服務器的AntDeploy&#xff0c; 在linux部署是需要安裝一個agent服務(systemctl服務)如果是手動第一次安裝的話 需要敲下載 wget解壓 tar修改配置文件的token復制到指定安裝目錄設置權限設置systemd設置systemctl清除臨時文件至少這8中類型的命…

UITableView的使用及代理方法

在App開放中我們經常會使用到UITabbleView&#xff0c;常用于數據展示。那么使用時不得不引入兩個代理方法<UITableViewDataSource,UITableViewDelegate>。 下面我們來簡單的創建一個TableView并介紹下其基本屬性。 property (nonatomic,strong) UITableView * myTable; …

Java集合和泛型練習及面試題——博客園:師妹開講啦

給定一段JAVA代碼如下&#xff1a;要打印出list中存儲的內容&#xff0c;以下語句正確的是&#xff08; B &#xff09; ArrayList list new ArrayList( ) list.add(“a”) list.add(“b”) Iterator it list.iterator( ) A.while(it. Next( ) )   system.out.prin…

對于經常需要truncate的表進行固定統計信息

為什么80%的碼農都做不了架構師&#xff1f;>>> 大家做過統計的一些存儲過程可能會知道&#xff0c;我們經常有這類表&#xff0c;要先truncate它&#xff0c;執行插入&#xff0c;再在執行相關sql&#xff0c;這就會導致有一個時間誤差&#xff0c;如果在truncate…

ArcGIS實驗教程——實驗四十一:ArcGIS區域分析統計直方圖(土地利用--坡度分級柱狀統計圖的制作)

文章目錄 一、任務描述二、實驗數據三、實驗過程一、任務描述 在實際工作中,通常需要統計不同類型的土地利用數據與坡度的關系。本實驗中以土地利用landuse和數字高程模型dem數據為例,基于ArcGIS平臺,統計了村莊、風景名勝、林地、草地、旱地等多種類型土地利用數據所占用的…

[轉]圖片格式WEBP全面解析

前言 不管是 PC 還是移動端&#xff0c;圖片一直是流量大頭&#xff0c;以蘋果公司 Retina 產品為代表的高 PPI 屏對圖片的質量提出了更高的要求&#xff0c;如何保證在圖片的精細度不降低的前提下縮小圖片體積&#xff0c;成為了一個有價值且值得探索的事情。 但如今對于 JP…

C語言試題189之編寫一個程序,按照下圖中的樣子創建數據結構,最后三個對象都是動態分配的結構。第一個對象則可能是一個靜態的指向結構的指針

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款刷算法、筆試、面經、拿大公司offer神器?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目: 編寫一…

基于.NetCore開發博客項目 StarBlog - (15) 生成隨機尺寸圖片

系列文章基于.NetCore開發博客項目 StarBlog - (1) 為什么需要自己寫一個博客&#xff1f;基于.NetCore開發博客項目 StarBlog - (2) 環境準備和創建項目基于.NetCore開發博客項目 StarBlog - (3) 模型設計基于.NetCore開發博客項目 StarBlog - (4) markdown博客批量導入基于.N…

【初探移動前端開發03】jQuery Mobile(上)

前言到目前為止&#xff0c;我打了幾天醬油了&#xff0c;這幾天落實了工作&#xff0c;并且看了一部電視連續劇&#xff08;陳道明-手機&#xff09;&#xff0c;我很少看連續劇了&#xff0c;但是手機質量很高啊&#xff0c;各位可以看看。我們今天先學習一下jquery mobile的…

Git Bash的一些命令和配置

查看git版本號&#xff1a; git --version 如果是第一次使用Git&#xff0c;你需要設置署名和郵箱&#xff1a; $ git config --global user.name "用戶名" $ git config --global user.email "電子郵箱" 檢查你的設置 $ git config --list 或單獨檢查一項…