摘要:子類繼承抽象類,并具體實(shí)現(xiàn)方法。抽象類的使用區(qū)別于具體類,抽象類無法直接創(chuàng)建抽象類對(duì)象,但是可以聲明抽象類的變量,引用抽象類對(duì)應(yīng)具體子類對(duì)象。接口優(yōu)于抽象類中討論到一條規(guī)則接口優(yōu)于抽象類。接口聲明能力,抽象類提供默認(rèn)實(shí)現(xiàn)全部或部分方法。
接口
類,強(qiáng)調(diào)數(shù)據(jù)類型(自定義)的概念,在一些情況下,并不能反映對(duì)象以及對(duì)象操作的本質(zhì)。有時(shí)我們關(guān)注的并非對(duì)象的類型,而是對(duì)象的能力。
接口聲明一組功能,作為協(xié)議(約定),但是自身不去實(shí)現(xiàn)功能方法。接口形式的交互涉及兩方對(duì)象:一方實(shí)現(xiàn)接口,另一方使用接口,雙方并不直接依賴,而是針對(duì)接口編程。
接口定義
接口定義即聲明方法,制定功能協(xié)議。
Java 使用 interface 關(guān)鍵字聲明接口,修飾符一般采用 public。
接口內(nèi)部聲明方法時(shí),通常不需要加修飾符,默認(rèn)視為 public abstract。
接口實(shí)現(xiàn)
類可以實(shí)現(xiàn)接口,表示類的對(duì)象具有接口(協(xié)議)制定的功能。
Java 使用 implements 關(guān)鍵字實(shí)現(xiàn)接口。
實(shí)現(xiàn)接口必須實(shí)現(xiàn)接口中聲明的所有方法。
public interface Printable { void print(); } public class A6 implements Printable { public void print() { System.out.println("Hello"); } public static void main(String args[]) { A6 obj = new A6(); obj.print(); } }
接口擴(kuò)展
接口可以擴(kuò)展另一個(gè)接口甚至多個(gè)接口,其方式與類可以擴(kuò)展(繼承)另一個(gè)類的方式相同,使用 extends 關(guān)鍵字,但是類的繼承限制為單繼承。
public interface BallGame extends Sport, Match {}
類的繼承與接口實(shí)現(xiàn)可以共存,并且類可以實(shí)現(xiàn)多個(gè)接口,從某種形式上構(gòu)成多繼承結(jié)構(gòu)。
public class Football extends Ball implements Sport, Match {}
等價(jià)于:
public class Football extends Ball implements BallGame {}
接口使用
與類不同,無法直接 new 創(chuàng)建接口對(duì)象,但是可以聲明接口類型的變量,引用實(shí)現(xiàn)了接口的類對(duì)象。
public interface Printable { void print(); } public class Main { public static void main(String args[]) { Printable obj = new Printable() { @Override public void print() { System.out.println("Hello"); } } obj.print(); } }
上述代碼看似創(chuàng)建接口對(duì)象,實(shí)則創(chuàng)建匿名內(nèi)部類對(duì)象,由其實(shí)現(xiàn)接口。
接口有時(shí)更能反映出對(duì)象的本質(zhì)(能力,一組功能協(xié)議)。所謂針對(duì)接口編程,使用接口而非具體實(shí)現(xiàn)接口的類型,統(tǒng)一處理不同類型對(duì)象,旨在降低耦合性,提高靈活性。當(dāng)然,接口本身由于沒有代碼實(shí)現(xiàn),并沒有太大用處,需要依賴具體實(shí)現(xiàn),才能生效。
抽象類抽象類,顧名思義抽象的類,一般代表多個(gè)具體類(子類)上層公共的父類,作為基類統(tǒng)一調(diào)用接口(方法)。
抽象類的意義抽象方法和抽象類密不可分,抽象方法是將來作為統(tǒng)一接口調(diào)用,而目前不知道如何實(shí)現(xiàn)的方法,只有通過子類重寫方法才能具體實(shí)現(xiàn)功能。
抽象類 Animal 定義 sound() 方法作為統(tǒng)一接口調(diào)用,因?yàn)闊o法確定 sound() 方法該如何具體實(shí)現(xiàn),Java 使用 abstract 關(guān)鍵字聲明方法為抽象方法,無需定義方法體。子類 Dog 繼承抽象類 Animal,并具體實(shí)現(xiàn) sound() 方法。
//abstract parent class abstract class Animal { //abstract method public abstract void sound(); } //Dog class extends Animal class public class Dog extends Animal { public void sound() { System.out.println("Woof"); } public static void main(String args[]) { Animal obj = new Dog(); obj.sound(); } }抽象類的使用
區(qū)別于具體類,抽象類無法直接 new 創(chuàng)建抽象類對(duì)象,但是可以聲明抽象類的變量,引用抽象類對(duì)應(yīng)具體子類對(duì)象。
定義了抽象方法的類必須聲明為抽象類,但是抽象類可以沒有抽象方法。
抽象類和具體類一樣,可以定義并實(shí)現(xiàn)具體方法,實(shí)例變量等。
一個(gè)類在繼承抽象類后,必須實(shí)現(xiàn)抽象類的所有抽象方法,除非類自己也聲明為抽象類。
抽象類介于接口和類之間。
接口與抽象類的區(qū)別及應(yīng)用場(chǎng)景相同點(diǎn)
無法創(chuàng)建對(duì)象(實(shí)例化)
抽象方法由具體類實(shí)現(xiàn)(統(tǒng)一接口)
作為引用變量指向具體類對(duì)象(多態(tài)性)
不同點(diǎn)
對(duì)比條件 | 接口 | 抽象類 |
---|---|---|
構(gòu)造器 | 不存在 | 可以有 |
具體方法 | 不存在 | 可以有 |
實(shí)例變量 | 不存在 | 可以有 |
“多繼承” | 支持 | 不支持 |
接口 = 純抽象類(所有方法都是抽象方法)
應(yīng)用場(chǎng)景
考慮多態(tài)性、統(tǒng)一接口調(diào)用的同時(shí),需要實(shí)例變量、帶有默認(rèn)實(shí)現(xiàn)的具體方法,使用抽象類。
聲明一組方法,卻又不想每個(gè)具體類都實(shí)現(xiàn)所有方法,可以使用抽象類,借助空方法,交由具體類自行決定重寫其感興趣的方法。
具體類已經(jīng)有父類,受 Java 限制只允許單繼承,只能選擇通過實(shí)現(xiàn)接口方式擴(kuò)展類。
《Effective Java》中討論到一條規(guī)則:“接口優(yōu)于抽象類”。基于如下論斷:
現(xiàn)有的類可以很容易被更新,以實(shí)現(xiàn)新的接口。
一般來說,無法更新現(xiàn)有的類來擴(kuò)展新的抽象類。如果希望讓兩個(gè)類擴(kuò)展同一個(gè)抽象類,就必須把抽象類放到類型層次的高處,這樣會(huì)間接地傷害到類層次,迫使這個(gè)公共祖先的所有子類都擴(kuò)展這個(gè)新的抽象類。接口是定義 mixin(混合類型)的理想選擇。
混合類型除了自身類型之外,還可以提供某些可選擇的行為。例如,實(shí)現(xiàn) Comparable 接口的實(shí)例之間可以相互比較。接口允許我們構(gòu)造非層次結(jié)構(gòu)的類型框架。
類型層次對(duì)于組織某些事物是非常合適的,但是并非所有事物都能被整齊地組織成一個(gè)嚴(yán)格的層次結(jié)構(gòu)。類層次過于臃腫缺乏靈活性,通過接口擴(kuò)展行為,一定程度上模擬多重繼承。
P.S. Java 限制只允許單繼承,即類不可能有一個(gè)以上的父類。
規(guī)則存在例外,即當(dāng)演變的容易性比靈活性和功能更為重要的時(shí)候,應(yīng)該使用抽象類來定義類型。抽象類的演變比接口的演變要容易得多,當(dāng)在抽象類中增加新的具體方法,它包含合理的默認(rèn)實(shí)現(xiàn),該抽象類的所有現(xiàn)有實(shí)現(xiàn)都將提供這個(gè)新的方法。接口一旦被公開發(fā)行,并且已被廣泛實(shí)現(xiàn),再想改變這個(gè)接口幾乎是不可能的。當(dāng)在公有接口中增加方法,不可避免破壞實(shí)現(xiàn)這個(gè)接口的所有現(xiàn)有的類。
書中建議程序員為“每個(gè)重要接口都提供一個(gè)抽象的骨架實(shí)現(xiàn)(skeletal implementation)類,把接口和抽象類的優(yōu)點(diǎn)結(jié)合起來。接口的作用仍然是定義類型,但是骨架實(shí)現(xiàn)類接管了所有與接口實(shí)現(xiàn)相關(guān)的工作。”
Java 類庫(kù)中存在許多一個(gè)接口對(duì)應(yīng)一個(gè)抽象類的設(shè)計(jì),例如:Collection 接口與 AbstractCollection 抽象類、List 接口與AbstractList 抽象類...。
抽象類和接口是配合而非替代關(guān)系。接口聲明能力,抽象類提供默認(rèn)實(shí)現(xiàn)(全部或部分方法)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/71771.html
摘要:依賴倒置原則是個(gè)設(shè)計(jì)原則中最難以實(shí)現(xiàn)的原則,它是實(shí)現(xiàn)開閉原則的重要途徑,依賴倒置原則沒有實(shí)現(xiàn),就別想實(shí)現(xiàn)對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。 1、單一職能原則(Single Responsibility Principle, SRP) 定義 There should never be more than one reason for a class to change.應(yīng)該有且僅有一個(gè)原因引起類的...
摘要:在我們做系統(tǒng)設(shè)計(jì)時(shí),經(jīng)常會(huì)設(shè)計(jì)接口或抽象類,然后由子類來實(shí)現(xiàn)抽象方法,這里使用的其實(shí)就是里氏替換原則。 1.開閉原則(Open Close Principle/OCP) 定義:一個(gè)類、模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。 開放-封閉原則的意思就是說,你設(shè)計(jì)的時(shí)候,時(shí)刻要考慮,盡量讓這個(gè)類是足夠好,寫好了就不要去修改了,如果新需求來,我們?cè)黾右恍╊惥屯晔铝耍瓉淼拇a能不動(dòng)則不動(dòng)。這個(gè)...
摘要:?jiǎn)我宦氊?zé)原則可以看做是低耦合高內(nèi)聚在面向?qū)ο笤瓌t上的引申,將職責(zé)定義為引起變化的原因,以提高內(nèi)聚性來減少引起變化的原因。抽象的穩(wěn)定性決定了系統(tǒng)的穩(wěn)定性,因?yàn)槌橄笫遣蛔兊模蕾囉诔橄笫敲嫦驅(qū)ο笤O(shè)計(jì)的精髓,也是依賴倒置原則的核心。 Java-面向?qū)ο?什么是面過程 把題分解成一個(gè)一個(gè)步驟,每個(gè)步驟用函數(shù)實(shí)現(xiàn),依次調(diào)用即可。就是說,在進(jìn)行面向過程 編程的時(shí)候,不需要考慮那么多,上來先定義一個(gè)...
摘要:前言是面對(duì)對(duì)象的語(yǔ)言,因此有必要單獨(dú)紀(jì)錄下對(duì)象的各種定義和理解。面對(duì)對(duì)象基本概述概述是基于面向過程的變成思想,是對(duì)面向過程的一種封裝。面對(duì)對(duì)象開發(fā)就是不斷的創(chuàng)建對(duì)象,使用對(duì)象,指揮對(duì)象做事情。面對(duì)對(duì)象設(shè)計(jì)其實(shí)就是在管理和維護(hù)對(duì)象之間的關(guān)系。 前言 java是面對(duì)對(duì)象的語(yǔ)言,因此有必要單獨(dú)紀(jì)錄下對(duì)象的各種定義和理解。 面對(duì)對(duì)象,主要包括:面向?qū)ο笏枷耄惻c對(duì)象及其使用,對(duì)象的內(nèi)存圖,成...
摘要:類的適配器結(jié)構(gòu)目標(biāo)角色這就是所期待得到的接口,由于是類適配器模式,因此目標(biāo)不可以是類。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類的一個(gè)包裝。和適配器模式的關(guān)系適配器模式的用意是改變所考慮對(duì)象的接口,而代理模式不能改變。 點(diǎn)擊進(jìn)入我的博客 3.1 適配器模式 適配器模式把一個(gè)類的接口變換成客戶端所期待的另一種接口,使得原本因接口不匹配而無法在一起工作的兩個(gè)類能夠在一起工作。 3...
閱讀 2626·2021-09-28 09:36
閱讀 2239·2021-09-07 09:58
閱讀 1499·2019-08-26 13:53
閱讀 1282·2019-08-23 17:53
閱讀 3034·2019-08-23 15:34
閱讀 1856·2019-08-23 15:34
閱讀 2872·2019-08-23 12:04
閱讀 3723·2019-08-23 10:56