理解Java接口與抽象類

引用:

深入理解Java的接口和抽象類-https://www.cnblogs.com/dolphin0520/p/3811437.html

接口和抽象類的區別-https://www.cnblogs.com/east7/p/10580245.html

    在面向對象的變成來說,抽象其一大特性,可以通過兩種形式體現OOP的抽象:抽象類和接口。而兩者雖然都體現了OOP的抽象,但其目的,特性是有所不同的,如下例:

    如果飛機繼承交通工具類挖掘機繼承製造工具類飛機挖掘機想使用同樣的加油方法那麼是沒有辦法通過繼承實現的,因爲類的繼承是單繼承。

    如果將加油行爲定義成是接口加油站,那麼飛機挖掘機想使用同樣的加油方法就很簡單了。寫一個接口讓飛機挖掘機實現這個接口就可以瞭如下圖:
在這裏插入圖片描述

一、抽象類

含有abstract修飾符的類即爲抽象類,抽象類是爲了繼承而存在

public abstract class Transport {
	abstract void drive();
	public void maintain() {
		System.out.println("保養維護");
	}
}

特點:

  • 抽象類不能實例化,只能通過繼承使用;
  • 在抽象類中,可以定義普通變量,普通方法/抽象方法,但是定義的抽象方法必須在具體子類中實現。
public class AirPlane extends Transport{
	@Override
	void drive() {
		System.out.println("dirve airplane");
	}
	public void maintain() {
		super.maintain();
		System.out.println("飛機保養維護");
	}
}
  • 抽象類中不一定包含抽象方法,但是有抽象方法的類必定是抽象類。
  • 構造方法,類方法(用 static 修飾的方法)不能聲明爲抽象方法。

相關概念辨析:

抽象類的子類必須給出抽象類中的抽象方法的具體實現,除非該子類也是抽象類。

abstract和final是不能共存的:抽象類需要被繼承才能使用,而被final修飾的類無法被繼承。

可以通過訪問修飾符publicprotecteddefault修飾其作用範圍:抽象類除了其抽象的定義外與普通類的使用類似。

抽象類可繼承一個類和實現多個接口。

二、接口

接口,英文稱作interface,在軟件工程中,接口泛指供別人調用的方法或者函數。從這裏,我們可以體會到Java語言設計者的初衷,它是對行爲的抽象。在Java中,定一個接口的形式如下:

[public] interface InterfaceName {
 
}

接口中的方法必須都是抽象方法,是一種極度抽象的類型,它比抽象類更加“抽象”,並且一般情況下不在接口中定義變量。

接口與類的區別:

  • 接口不能用於實例化對象。
  • 接口沒有構造方法。
  • 接口中所有的方法必須是抽象方法。
  • 接口不能包含成員變量,除了 static 和 final 變量。
  • 接口不是被類繼承了,而是要被類實現。
  • 接口支持多繼承。

接口特性

  • 接口中每一個方法也是隱式抽象的,接口中的方法會被隱式的指定爲 public abstract(只能是 public abstract,其他修飾符都會報錯)。
  • 接口中可以含有變量,但是接口中的變量會被隱式的指定爲 public static final 變量(並且只能是 public,用 private 修飾會報編譯錯誤)。
  • 接口中的方法是不能在接口中實現的,只能由實現接口的類來實現接口中的方法。

三、異同對比

抽象類和接口的區別

1.語法層面上的區別

  • 抽象類中的方法可以有方法體,就是能實現方法的具體功能,但是接口中的方法不行。
  • 抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是 public static final 類型的。
  • 接口中不能含有靜態代碼塊以及靜態方法(用 static 修飾的方法),而抽象類是可以有靜態代碼塊和靜態方法。
  • 一個類只能繼承一個抽象類,而一個類卻可以實現多個接口。
性質 抽象類 接口
訪問修飾符 publicprotecteddefault 只有****public
多繼承 繼承一個類和實現多個接口 只可以繼承一個或多個其它接口
是否有構造函數
main方法 支持 不支持
方法實體實現 支持 不支持,接口完全是抽象的
與正常Java類的區別 不能實例化抽象類,因爲有abstract方法 接口是完全不同的類型
使用: 子類使用extends關鍵字來繼承抽象類,實現所有抽象方法** 子類使用關鍵字implements來實現接口,需要實現接口中聲明的所有方法
速度 速度快 稍微有點慢,因爲它需要時間去尋找在類中實現的方法
添加新方法 添加後可以給它提供默認的實現,故不需要改變現在的代碼 添加後必須改變實現該接口的類

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進行改動。

​     而輻射式設計,比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更新。

​     也就是說對於抽象類,如果需要添加新的方法,可以直接在抽象類中添加具體的實現,子類可以不進行變更;而對於接口則不行,如果接口進行了變更,則所有實現這個接口的類都必須進行相應的改動。

什麼時候使用抽象類和接口?

•如果擁有一些方法並且想讓它們中的一些有默認實現,那麼使用抽象類。

•如果想實現多重繼承,那麼必須使用接口。由於Java不支持多繼承,子類不能夠繼承多個類,但可以實現多個接口。因此就可以使用接口來解決它。

•如果基本功能在不斷改變,那麼就需要使用抽象類。如果不斷改變基本功能並且使用接口,那麼就需要改變所有實現了該接口的類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章