Java—接口与抽象类
一、接口
Java編程語言中禁止多繼承屬性,但可以通過接口來幫助類擴展方法。接口中可以定義大量的常量和方法,但其中的方法只是一種聲明,沒有具體的實現,使用接口的類自己實現這些方法。
接口與類的不同在于:
?(1) 沒有變量的聲明,但可以定義常量。
?(2) 只有方法的聲明,沒有方法的實現。
?1. 接口聲明的基本格式如下:
[修飾符] interface 接口名 extends 接口列表{[public] [static] [final] 常量;[public] [abstract] 方法;}修飾符:可選,用于指定接口的訪問權限,可選值為public,如果省略則使用默認的訪問權限。
接口中的變量會被隱式地指定為public static final變量(并且只能是public static final變量,用private修飾會報編譯錯誤),
而方法會被隱式地指定為public abstract方法且只能是public abstract方法(用其他關鍵字,比如private、protected、static、 final等修飾會報編譯錯誤)。
package test;public interface CalInterface {final float PI=3.14159f;//定義用于表示圓周率的常量PIfloat getArea(float r);//定義一個用于計算面積的方法getArea()float getCircumference(float r);//定義一個用于計算周長的方法getCircumference() }2.實現接口
要讓一個類遵循某組特地的接口需要使用implements關鍵字,具體格式如下:
[修飾符] class <類名> [extends 父類名] [implements 接口列表]{}
修飾符:可選參數,用于指定類的訪問權限,可選值為public、abstract和final。
類名:必選參數,用于指定類的名稱,類名必須是合法的Java標識符。一般情況下,要求首字母大寫。
extends 父類名:可選參數,用于指定要定義的類繼承于哪個父類。當使用extends關鍵字時,父類名為必選參數。
implements 接口列表:可選參數,用于指定該類實現的是哪些接口。當使用implements關鍵字時,接口列表為必選參數。當接口列表中存在多個接口名時,各個接口名之間使用逗號分隔。
在類中實現接口時,方法的名字、返回值類型、參數的個數及類型必須與接口中的完全一致,并且必須實現接口中的所有方法。
例如,新建一個Cire的類,該類實現定義的接口Calculate,具體代碼如下:
package test;public class Cire implements CalInterface {public float getArea(float r) {float area=PI*r*r;//計算圓面積并賦值給變量areareturn area;//返回計算后的圓面積 }public float getCircumference(float r) {float circumference=2*PI*r; //計算圓周長并賦值給變量circumferencereturn circumference; //返回計算后的圓周長 }public static void main(String[] args) {Cire c = new Cire();float f = c.getArea(2.0f);System.out.println(Float.toString(f));} }在對象內部,我們利用this來調用對象的數據成員和方法。
在對象外部,比如當我們在另一個類中調用對象的時,可以使用 對象.數據成員 和 對象.方法() 來調用對象的數據成員和方法。
封裝:即保留有限的外部接口,隱藏具體細節,提高易用性。
二、抽象類 抽象方法是一種特殊的方法:它只有聲明,而沒有具體的實現。抽象方法的聲明格式為: abstract void fun();抽象方法必須用abstract修飾,如果一個類含有抽象方法,則稱這個類為抽象類,抽象類必須在類前用abstract關鍵字修飾。因為抽象類中含有無具體實現的方法,所以不能用抽象類創建對象。
[public] abstract class ClassName { abstract void fun(); }從這里可以看出,抽象類就是為了繼承而存在的,如果你定義了一個抽象類,卻不去繼承它,那么等于白白創建了這個抽象類,因為你不能用它來做任何事情。對于一個父類,如果它的某個方法在父類中實現出來沒有任何意義,必須根據子類的實際需求來進行不同的實現,那么就可以將這個方法聲明為abstract方法,此時這個類也就成為abstract類了。
包含抽象方法的類稱為抽象類,但并不意味著抽象類中只能有抽象方法,它和普通類一樣,同樣可以擁有成員變量和普通的成員方法。注意,抽象類和普通類的主要有三點區別:
1)抽象方法必須為public或者protected(因為如果為private,則不能被子類繼承,子類便無法實現該方法),缺省情況下默認為public。
2)抽象類不能用來創建對象;
3)如果一個類繼承于一個抽象類,則子類必須實現父類的抽象方法。如果子類沒有實現父類的抽象方法,則必須將子類也定義為為abstract類。
在其他方面,抽象類和普通的類并沒有區別。
三、抽象類與接口的區別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() { //.... } }?
?
?
轉載于:https://www.cnblogs.com/feitiannengdou/p/5442708.html
總結
以上是生活随笔為你收集整理的Java—接口与抽象类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 键盘鼠标模拟全知道
- 下一篇: eclipse 高效快捷键大全