Java抽象类、接口、类的特殊成员
抽象類
在面向對象的概念中,所有的對象都是通過類來描繪的,但是并不是所有的類都是用來描繪對象的.
如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。
抽象類往往用來表征我們在對問題領域進行分析、設計中得出的抽象概念,是對一系列看上去不同,但是本質上相同的具體概念的抽象。
比如:如果我們進行一個圖形編輯軟件的開發,就會發現問題領域存在著圓、三角形 這樣一些具體概念,它們是不同的,但是它們又都屬于形狀這樣一個概念,形狀這個概念在問題領域是不存在的,它就是一個抽象概念。正是因為抽象的概念在問題領域沒有對應的具體概念,所以用以表征抽象概念的抽象類是不能夠實例化的。
抽象方法:一種特殊的方法,它只有聲明,而沒有具體的實現(無方法體)。抽象方法的聲明格式為:
abstract void f();抽象方法必須用abstract關鍵字進行修飾。abstract 只能修飾類或類中的成員方法,不能修飾屬性。被修飾的類或方法分別稱作抽象類或抽象方法。其中抽象方法不能有方法體,而抽象類不能實例化,如果一個類含有抽象方法,則這個類一定為抽象類,抽象類必須在類前用abstract關鍵字修飾。當然,抽象類也可以沒有抽象方法。
abstract class Test1{abstract void f();//正確, 抽象方法不能有方法體abstract void g(){;}//編譯錯, 抽象方法不能有方法體void h();//編譯錯, 非抽象類必須有方法體 }【注意】:abstract 不能修飾最終方法、靜態方法或構造函數,因為這三類方法都不能被子類重寫。
abstract class Test2{abstract Test2();//編譯錯, 構造函數不能被abstract修飾abstract final void f();編譯錯, final方法不能被abstract修飾abstract static void g();編譯錯, 靜態方法不能被abstract修飾 }- 抽象類是契約的重量級應用方式
- 接口是契約的輕量級應用方式
接口
Java接口是一系列方法的聲明,是一些方法特征的集合,一個接口只有方法的特征沒有方法的實現,因此這些方法可以在不同的地方被不同的類實現,而這些實現可以具有不同的行為(功能)。接口可以理解為一種特殊的類,里面全部是由全局常量和公共的抽象方法所組成。接口是解決Java無法使用多繼承的一種手段,但是接口在實際中更多的作用是制定標準的。或者我們可以直接把接口理解為100%的抽象類,既接口中的方法必須全部是抽象方法。
特點:
- 就像一個類一樣,一個接口也能夠擁有方法和屬性,但是在接口中聲明的方法默認是抽象的。(即只有方法標識符,而沒有方法體)。
- 接口指明了一個類必須要做什么和不能做什么,相當于類的藍圖。
- 一個接口就是描述一種能力,比如“運動員”也可以作為一個接口,并且任何實現“運動員”接口的類都必須有能力實現奔跑這個動作(或者implement move()方法),所以接口的作用就是告訴類,你要實現我這種接口代表的功能,你就必須實現某些方法,我才能承認你確實擁有該接口代表的某種能力。
- 如果一個類實現了一個接口中要求的所有的方法,然而沒有提供方法體而僅僅只有方法標識,那么這個類一定是一個抽象類。(必須記住:抽象方法只能存在于抽象類或者接口中,但抽象類中卻能存在非抽象方法,即有方法體的方法。接口是百分之百的抽象類)。
為什么要用接口:
- 接口被用來描述一種抽象。
- 因為Java不像C++一樣支持多繼承,所以Java可以通過實現接口來彌補這個局限。
- 接口也被用來實現解耦。
- 接口被用來實現抽象,而抽象類也被用來實現抽象,為什么一定要用接口呢?- 接口和抽象類之間又有什么區別呢?原因是抽象類內部可能包含非final的變量,但是在接口中存在的變量一定是final,public, static的。
接口的實現:
[修飾符] interface 接口名 [extends 父接口列表]{[public][static][final]類型 成員常量 = 常量值[public][abstract] 返回類型 成員方法名([參數列表]) }具體的例子:
我們知道,如果某個設備需要向電腦中讀取或者寫入某些東西,這些設備一般都是采用USB方式與電腦連接的,我們發現,只要帶有USB功能的設備就可以插入電腦中使用了,那么我們可以認為USB就是一種功能,這種功能能夠做出很多的事情(實現很多的方法),其實USB就可以看做是一種標準,一種接口,只要實現了USB標準的設備我就認為你已經擁有了USB這種功能。(因為你實現了我USB標準中規定的方法)。
運行結果
U盤正在通過USB功能讀取數據 U盤正在通過USB功能寫入數據 鍵盤正在通過USB功能讀取數據 鍵盤正在通過USB功能寫入數據【注意】:
1)接口不是類,接口中的方法都是抽象的,是沒有方法體的沒有構造函數,也不能實例化出對象。
2)一個類可以實現不止一個接口。
3)一個接口可以繼承于另一個接口,或者另一些接口,接口也可以繼承,并且可以多繼承。
4)一個類如果要實現某個接口的話,那么它必須要實現這個接口中的所有方法。
5)接口中所有的方法都是抽象的和public的,所有的屬性都是public,static,final的。
6)接口用來彌補類無法實現多繼承的局限。
7)接口也可以用來實現解耦。
類中的特殊成員
——內嵌類型、初始化塊、本地方法
內嵌類型
內嵌類型就是在類或接口內部定義的自定義類型,你包括內部類和內部接口。包圍內部類或內部接口的類稱為囿類型,或包圍類型、外部類型等。
class A{ //A是包圍類class B{ //內部類int x;}interface C{ //內部接口int y = 0;} } 編譯后將產生三個文件:A.class、A$B.class、A$C.classinterface X{ //X是包圍接口class Y{ //內部類int x;}interface Z{ //內部接口int y = 0;} } 編譯后將產生三個文件:X.class、X$Y.class、X$Z.class內部類存取規則:
1、作為囿類的成員,內部類可以存取囿類的其他所有成員,包括私有成員。
2、存取內部類及其成員必須要借助囿類或囿類的對象。顯然,若囿類對象不能訪問,那么內部類也不能訪問。
1、內部類和囿類可以任意訪問,沒有權限上的限制。但囿類成員方法訪問內部類成員,必須要借助內部類的對象,反之則無此限制。
2、在囿類外部,只要權限允許,也可以通過囿類對象訪問內部類的成員,如ab.h2();。但是,ab.y=6則編譯錯誤,因為權限不允許。
3、兩種在外部獲取內部類對象的方式:
1)通過囿類的public方法返回,如a.g();。
2)直接調用內部類的構造函數,但方式特殊,如new A().new B();或者a.new B();。
靜態內部類
Java規定:若內部類中有靜態成員,則該內部類必須是靜態內部類。
測試靜態類和非靜態類
成員內部類(可以使用private、default、 protected、 public任意進行修飾。類文件:外部類$內部類.class)
a)非靜態內部類(外部類里使用非靜態內部類和平時使用其他類沒什么不同)
i. 非靜態內部類必須寄存在一個外部類對象里。因此,如果有一個非靜態內部類對象那么一定存在對應的外部類對象。非靜態內部類對象單獨屬于外部類的某個對象。
ii. 非靜態內部類可以直接訪問外部類的成員,但是外部類不能直接訪問非靜態內部類成員。
iii. 非靜態內部類不能有靜態方法、靜態屬性和靜態初始化塊。
iv. 外部類的靜態方法、靜態代碼塊不能訪問非靜態內部類,包括不能使用非靜態內部類定義變量、創建實例。
v. 成員變量訪問要點:
1.內部類里方法的局部變量:變量名。
2.內部類屬性: this.變量名。
3.外部類屬性:外部類名.this.變量名。
局部內部類和匿名內部類
成員方法中只有局部變量、常量、內部類相應地稱作局部內部類。局部變量不能用權限屬性、static、abstract等屬性的修飾,局部內部類也是如此。局部內部類的作用范圍,僅限于其所在的方法。
沒有名字的內部類成為匿名類
public class Ch_4_28{public static void main (String[] args) {A a=new A() { //定義A的匿名子類(匿名的局部內部類) public void f(){System.out.println("匿名類.f()");}public void g(){;} //可通過編譯但無法使用}; //作為語句結束符的分號不能少,匿名類定義結束a.f();// a.g(); //編譯錯,因為a是A類型,A中無g()方法} } class A{public void f(){ System.out.println("A.f()"); } }初始化塊
初始化塊就是在類中獨立于成員方法之外的代碼段,它沒有名字,不帶參數,無返回值。被static修飾就是靜態初始化塊,否則就是實力初始化塊。初始化塊的執行遵循以下規則:
1)初始塊的執行順序遵循其出現的次序。
2)實例初始化塊先于構造函數。
3)靜態初始化塊在類中的初次加載時執行,僅執行一次,且先于實例初始化塊。
總結
以上是生活随笔為你收集整理的Java抽象类、接口、类的特殊成员的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【操作系统复习】操作系统的发展与分类
- 下一篇: linux标准I/O——流的打开和关闭