Java面向对象基础接口和抽象的理解
第一,抽象類:
我們都知道,在面向對象的領域中,一切都是一個對象,所有的對象都是用類來描述的,但不是所有的類都是用對象來描述的。如果一個類沒有足夠的信息來描述一個特定的對象,并且需要其他特定的類來支持它,那么我們稱它為抽象類。例如,新動物(),我們都知道這是為了生產一種動物-動物-動物的物體,但我們不知道動物是什么樣子的。它沒有特定動物的概念,因此它是一個抽象類。我們需要一種特殊的動物,比如狗和貓,以一種特定的方式來描述它,這樣我們就能知道它是什么樣子的。
在面向對象的領域中,抽象概念在問題域中沒有對應的具體概念,因此無法實例化表示抽象概念的抽象類。
同時,抽象類體現了數據抽象的思想,是實現多態性的一種機制。它定義了一組抽象方法,并使用派生類來表示它們。同時,抽象類提供了繼承的概念,其出發點是繼承,否則就不存在任何意義上的繼承。因此,定義的抽象類必須用于繼承。同時,在以抽象類為節點的繼承關系層次鏈中,葉節點必須是具體的實現類。
使用抽象類時需要注意以下幾點:
無法實例化抽象類。實例化的工作應該留給它的子類。它只需要一個參考。
抽象方法必須由子類重寫。
只要它包含一個抽象方法的抽象類,該方法就必須被定義為一個抽象類,不管它是否包含其他方法。
抽象類可以包含具體方法,但也不能包含抽象方法。
抽象不能與final并排修改同一個類。
抽象不能同時使用private、static、final或native修改同一方法。
例子:
定義一個抽象的動物類動物,并提供一個名為cry()的抽象方法。貓和狗都是動物類的子類。因為cry()是一個抽象方法,所以cat和dog必須實現cry()方法。如下:
public abstract class Animal {
public abstract void cry();
}
public class Cat extends Animal{
@Override
public void cry() {
System.out.println("貓叫:喵喵...");
}
}
public class Dog extends Animal{
@Override
public void cry() {
System.out.println("狗叫:汪汪...");
}
}
public class Test {
public static void main(String[] args) {
Animal a1 = new Cat();
Animal a2 = new Dog();
a1.cry();
a2.cry();
}
}
創建抽象類和方法非常有用,因為它們可以澄清類的抽象性,并告訴用戶和編譯器如何使用它們。抽象類是有用的重構器,因為它們允許我們輕松地將通用方法向繼承層次結構上移動。
?
二、接口
接口比抽象類更抽象。我在這里找不到一個更好的單詞來引用“class”,但是讓我們澄清一下,接口本身不是一個類,正如我們不能實例化接口的事實所看到的那樣。例如,new runnable();必須是錯誤的,我們只能新建它的實現類。
接口用于在類之間建立協議,這些類只提供沒有特定實現的表單。同時,實現接口的實現類必須實現接口的所有方法。通過使用implements關鍵字,他指示類正在跟蹤特定接口或一組特定接口。同時,他還指出“接口只是它的外觀,但現在我們需要聲明它是如何工作的”。
接口是抽象類的擴展。Java保證沒有多重繼承的數據安全性。也就是說,繼承只能存在于一個父類中。但是不同的接口,一個類可以同時實現多個接口。不管這些接口之間是否存在任何關系,接口彌補了抽象類不能繼承多個接口的不足,但建議繼承和接口一起使用,因為這兩者都是。它可以保證數據安全,實現多重繼承。
在使用界面的過程中,應注意以下問題:
接口的所有方法訪問權限都自動聲明為公共。確切地說,它只能是公開的。當然,您可以將聲明顯示為受保護的和私有的,但是編譯會出錯!
成員變量或不可變常量可以在接口中定義,因為它們自動成為公共靜態final。通過類命名直接訪問:實現類。姓名。
接口中沒有實現方法。
實現接口的非抽象類必須實現接口的所有方法。抽象類可以在不需要的情況下實現。
不能使用new運算符實例化接口,但可以聲明一個接口變量,該變量必須引用實現接口的類的對象。可以使用InstanceOf檢查對象是否實現特定接口。例如:if(AnObject Instance of Comparable)。
在實現多個接口時,必須避免方法名的重復。
三、抽象類與接口的區別
盡管抽象類和接口有很多共同點,有時它們可以互換,但這并不能彌補它們之間的差異。接下來,抽象類和接口將從兩個方面進行闡述:語法級別和設計級別。
3.1語法水平
在語法層面上,Java語言給出抽象類和接口的不同定義。下面的演示類說明了它們之間的區別。
使用抽象類實現:
public abstract class Demo {? abstract void method1();? void method2(){? //實現? } }
使用接口實現
interface Demo {? void method1();? void method2(); }
在抽象類方法中,抽象類可以有任意范圍的成員數據,也可以有自己的非抽象方法。但在接口方法中,它只能有靜態和不可修改的成員數據(但我們通常不在接口中使用成員數據)。同時,它的所有方法都必須是抽象的。在某種程度上,接口是抽象類的專門化。
對于子類,它只能繼承一個抽象類(它被Java考慮用于數據安全),但是它可以實現多個接口。
3.2設計水平
以上只是從語法層次和編程角度來區分它們之間的關系,這些都是低級的,要真正使用抽象類和接口,我們必須從更高層次來區分。只有從設計理念的角度才能看到它們的本質。一般來說,它們有以下三個區別:
抽象的層次是不同的。抽象類是類的抽象,接口是行為的抽象。抽象類是抽象整個類,包括屬性、行為,而接口是抽象類的局部(行為)。
跨領域差異。抽象類跨具有相似特性的域,而接口可以跨具有不同類的域。我們知道抽象類從子類中發現公共部分,然后歸納為抽象類。子類可以繼承父類,但接口不同。實現它的子類之間不能有任何共同點。例如,貓和狗可以用吠叫方法抽象成一個抽象的動物類。鳥類和飛機可以實現飛行界面,具有飛行行為。我們不能在這里和父母一人分享鳥類和飛機。所以抽象類體現了一種繼承關系。為了使繼承關系合理化,父類和派生類之間必須有一個“is-a”關系,即父類和派生類的概念在本質上應該是相同的。然而,對于接口,它并不要求接口的實現者和接口定義的實現者在概念上基本相同,而是只實現接口定義的契約。
設計水平不同。對于抽象類,它是自下而上設計的。在抽象父類之前,我們需要知道子類,但是接口是不同的。它根本不需要知道子類的存在。它只需要定義一個規則,我們不知道什么子類,何時以及如何實現它們。例如,我們這里只有一只貓。如果你把它抽象成動物,它是不是有點設計過度了?我們這里至少應該有兩個動物班,貓和狗。讓我們抽象它們的共同點,形成動物抽象類。所以抽象類經常被重構!但是界面是不同的。例如,飛行,我們不知道什么將實現飛行接口。如何實現它還不得而知。我們需要做的是預先定義好飛行的行為界面。所以抽象類是從下到上抽象的,接口是從上到下設計的。
為了更好地說明它們之間的差異,將使用一個示例來說明以下內容。這個例子引用自:blog。CSDN網/ttgjz/arti…
我們有一個門的抽象概念,它有兩個行為,打開()和關閉(),我們可以通過抽象類和接口來定義抽象概念:
抽象類:
abstract class Door{? abstract void open();? abstract void close(); }
界面
interface Door{? void open();? void close(); }
對于其他具體類,可以使用擴展類和抽象類來定義門,也可以使用接口實現來定義門。結果表明,二者之間無顯著性差異。
但是現在如果我們需要一個具有報警功能的門,那么如何實現它呢?
解決方案1:向門添加報警方法:clarm();
abstract class Door{? abstract void open();? abstract void close();? abstract void alarm(); }
也許
interface Door{? void open();? void close();? void alarm(); }
這種方法違反了面向對象設計的核心原則之一ISP(接口分離原則)。請注意,在門的定義中,它將門概念的固有行為方法與另一個概念“報警”的行為方法混合在一起。出現的一個問題是,僅依賴門概念的模塊將隨著“警報”概念的變化而變化,反之亦然。
解決方案2
由于open()、close()和alarm()屬于兩個不同的概念,我們根據isp原理將它們分別定義為表示兩個不同概念的兩個抽象類。定義它們有三種方法:
1。兩者都由抽象類定義。
2。兩者都由接口定義。
3、一個使用抽象類定義,一個是用接口定義。
因為Java不支持多重繼承,所以第一個是不可行的。后兩種方法是可行的,但是選擇反映了您對問題域本質的理解。
如果第二個問題是由接口定義的,那么它反映了兩個問題:1。我們可能不清楚問題域,而報警門本質上是一個門到門的報警。2。例如,如果我們對問題域的理解沒有問題,我們已經確定在我們的分析中,報警門的概念本質上是相同的,那么我們在設計中沒有正確地反映我們的設計意圖。因為您使用兩個接口來定義,所以它們的概念的定義并不反映上述含義。
第三,如果我們理解問題域如下:報警門本質上是一個門,但它也具有報警的行為功能,那么我們可以使用第三種方案來說明我們的設計意圖。報警門本質上是人,所以我們使用抽象類來定義這個概念。同時,報警門具有報警功能,表明它能夠完成報警概念中定義的行為功能,因此報警可以使用接口來定義報警門。如下:
abstract class Door{? abstract void open();? abstract void close(); } interface Alarm{? void alarm(); } class AlarmDoor extends Door implements Alarm{? void open(){}? void close(){}? void alarm(){} }
這種實現方式基本上可以清楚地反映我們對問題領域的理解,并正確地揭示我們的設計意圖。實際上,抽象類表示“is-a”關系,接口表示“like-a”關系。每個人都可以選擇它作為基礎。當然,這是基于對問題域的理解。例如,如果我們認為報警門在概念上本質上是一個報警,并且具有門的功能,那么上述定義將被顛倒。
注釋:
isp(接口分離原則):面向對象的核心原則。結果表明,使用多個專用接口優于使用單個主接口。
一個類與另一個類的依賴關系應該基于最小的接口。
接口代表一個角色,不應將不同的角色分配給一個接口。不相關的接口合并在一起形成一個膨脹的大接口,這是角色和接口的污染。
四、總結
1。抽象類表示Java語言中的繼承關系。子類只能有一個父類,但可以有多個接口。
2。在抽象類中,我們可以有自己的成員變量和非抽象類方法,但是在接口中只能有靜態和不可變的成員數據(盡管我們通常不在接口中定義成員數據),并且它的所有方法都是抽象的。
三。抽象類和接口反映了不同的設計概念。抽象類表示“is-a”關系,而接口表示“like-a”關系。
抽象類和接口是Java語言中的兩種不同抽象概念。它們的存在為多態性提供了很好的支持,盡管它們之間有很大的相似性。但他們的選擇往往反映出你對問題領域的理解。只有對問題域的性質有了很好的了解,才能做出正確合理的設計。
?為了讓學習變得輕松、高效,今天給大家免費分享一套Java教學資源。幫助大家在成為Java架構師的道路上披荊斬棘。需要資料的歡迎加入學習交流群:9285,05736
總結
以上是生活随笔為你收集整理的Java面向对象基础接口和抽象的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql lock_MySQL-锁总结
- 下一篇: 平移刚体上各点的加速度和速度_大物学习笔