好處:java
提升了代碼的複用性。 讓類與類之間產生了關係,提供了另外一個特徵多態的前提。
父類的由來:設計模式
實際上是由多個類不斷向上抽取共性內容而來的。
java中對於繼承,java只支持單繼承。java雖然不直接支持多繼承,可是保留了這種多繼承機制,進行改良。
單繼承:函數
一個類只能有一個父類。
多繼承:this
一個類能夠有多個父類。
爲何不支持多繼承呢?
由於當一個類同時繼承兩個父類時,兩個父類中有相同的功能,那麼子類對象調用該功能時,運行哪個呢?由於父類中的方法中存在方法體。
可是java支持多重繼承。A繼承B B繼承C C繼承D。
多重繼承的出現,就有了繼承體系。體系中的頂層父類是經過不斷向上抽取而來的。它裏面定義的該體系最基本最共性內容的功能。
因此,一個體系要想被使用,直接查閱該系統中的父類的功能便可知道該體系的基本用法。那麼想要使用一個體系時,須要創建對象。建議創建最子類對象,由於最子類不只可使用父類中的功能。還可使用子類特有的一些功能。設計
簡單說:code
對於一個繼承體系的使用,查閱頂層父類中的內容,建立最底層子類的對象。
子父類出現後,類中的成員都有了哪些特色:對象
1:成員變量。繼承
當子父類中出現同樣的屬性時,子類類型的對象,調用該屬性,值是子類的屬性值。接口
若是想要調用父類中的屬性值,須要使用一個關鍵字:super內存
This:表明是本類類型的對象引用。
Super:表明是子類所屬的父類中的內存空間引用。
注意:子父類中一般是不會出現同名成員變量的,由於父類中只要定義了,子類就不用在定義了,直接繼承過來用就能夠了。
2:成員函數。
當子父類中出現瞭如出一轍的方法時,創建子類對象會運行子類中的方法。好像父類中的方法被覆蓋掉同樣。因此這種狀況,是函數的另外一個特性:覆蓋(複寫,重寫)
何時使用覆蓋呢?當一個類的功能內容須要修改時,能夠經過覆蓋來實現。
3:構造函數。
發現子類構造函數運行時,先運行了父類的構造函數。爲何呢?
緣由:子類的全部構造函數中的第一行,其實都有一條隱身的語句super();
super(): 表示父類的構造函數,並會調用於參數相對應的父類中的構造函數。而super():是在調用父類中空參數的構造函數。
爲何子類對象初始化時,都須要調用父類中的函數?(爲何要在子類構造函數的第一行加入這個super()?)
由於子類繼承父類,會繼承到父類中的數據,因此必需要看父類是如何對本身的數據進行初始化的。因此子類在進行對象初始化時,先調用父類的構造函數,這就是子類的實例化過程。
注意:子類中全部的構造函數都會默認訪問父類中的空參數的構造函數,由於每個子類構造內第一行都有默認的語句super();
若是父類中沒有空參數的構造函數,那麼子類的構造函數內,必須經過super語句指定要訪問的父類中的構造函數。
若是子類構造函數中用this來指定調用子類本身的構造函數,那麼被調用的構造函數也同樣會訪問父類中的構造函數。
問題:super()和this()是否能夠同時出現的構造函數中。
兩個語句只能有一個定義在第一行,因此只能出現其中一個。
super()或者this():爲何必定要定義在第一行?
由於super()或者this()都是調用構造函數,構造函數用於初始化,因此初始化的動做要先完成。
繼承的細節:
何時使用繼承呢?
當類與類之間存在着所屬關係時,才具有了繼承的前提。a是b中的一種。a繼承b。狼是犬科中的一種。
英文書中,所屬關係:" is a "
注意:不要僅僅爲了獲取其餘類中的已有成員進行繼承。
因此判斷所屬關係,能夠簡單看,若是繼承後,被繼承的類中的功能,均可以被該子類所具有,那麼繼承成立。若是不是,不能夠繼承。
細節二:
在方法覆蓋時,注意兩點:
1:子類覆蓋父類時,必需要保證,子類方法的權限必須大於等於父類方法權限能夠實現繼承。不然,編譯失敗。
2:覆蓋時,要麼都靜態,要麼都不靜態。 (靜態只能覆蓋靜態,或者被靜態覆蓋)
繼承的一個弊端:打破了封裝性。對於一些類,或者類中功能,是須要被繼承,或者複寫的。
這時如何解決問題呢?介紹一個關鍵字,final:最終。
final特色:
1:這個關鍵字是一個修飾符,能夠修飾類,方法,變量。
2:被final修飾的類是一個最終類,不能夠被繼承。
3:被final修飾的方法是一個最終方法,不能夠被覆蓋。
4:被final修飾的變量是一個常量,只能賦值一次。
其實這樣的緣由的就是給一些固定的數據起個閱讀性較強的名稱。
不加final修飾不是也可使用嗎?那麼這個值是一個變量,是能夠更改的。加了final,程序更爲嚴謹。常量名稱定義時,有規範,全部字母都大寫,若是由多個單詞組成,中間用 _ 鏈接。
抽象類: abstract
抽象:不具體,看不明白。抽象類表象體現。
在不斷抽取過程當中,將共性內容中的方法聲明抽取,可是方法不同,沒有抽取,這時抽取到的方法,並不具體,須要被指定關鍵字abstract所標示,聲明爲抽象方法。
抽象方法所在類必定要標示爲抽象類,也就是說該類須要被abstract關鍵字所修飾。
抽象類的特色:
1:抽象方法只能定義在抽象類中,抽象類和抽象方法必須由abstract關鍵字修飾(能夠描述類和方法,不能夠描述變量)。
2:抽象方法只定義方法聲明,並不定義方法實現。
3:抽象類不能夠被建立對象(實例化)。
4:只有經過子類繼承抽象類並覆蓋了抽象類中的全部抽象方法後,該子類才能夠實例化。不然,該子類仍是一個抽象類。
抽象類的細節:
1:抽象類中是否有構造函數?有,用於給子類對象進行初始化。
2:抽象類中是否能夠定義非抽象方法?
能夠。其實,抽象類和通常類沒有太大的區別,都是在描述事物,只不過抽象類在描述事物時,有些功能不具體。因此抽象類和通常類在定義上,都是須要定義屬性和行爲的。只不過,比通常類多了一個抽象函數。並且比通常類少了一個建立對象的部分。
3:抽象關鍵字abstract和哪些不能夠共存?final ,private , static
4:抽象類中可不能夠不定義抽象方法?能夠。抽象方法目的僅僅爲了避免讓該類建立對象。
模板方法設計模式:
解決的問題:當功能內部一部分實現時肯定,一部分實現是不肯定的。這時能夠把不肯定的部分暴露出去,讓子類去實現。
abstract class GetTime{
public final void getTime(){ //此功能若是不須要複寫,可加final限定
long start = System.currentTimeMillis();
code(); //不肯定的功能部分,提取出來,經過抽象方法實現
long end = System.currentTimeMillis();
System.out.println("毫秒是:"+(end-start));
}
public abstract void code(); //抽象不肯定的功能,讓子類複寫實現
}
class SubDemo extends GetTime{
public void code(){ //子類複寫功能方法
for(int y=0; y<1000; y++){
System.out.println("y");
}
}
}
接 口:★★★★★
1:是用關鍵字interface定義的。
2:接口中包含的成員,最多見的有全局常量、抽象方法。
注意:接口中的成員都有固定的修飾符。
成員變量:public static final
成員方法:public abstract
interface Inter{
public static final int x = 3;
public abstract void show();
}
3:接口中有抽象方法,說明接口不能夠實例化。接口的子類必須實現了接口中全部的抽象方法後,該子類才能夠實例化。不然,該子類仍是一個抽象類。
4:類與類之間存在着繼承關係,類與接口中間存在的是實現關係。
繼承用extends ;實現用implements ;
5:接口和類不同的地方,就是,接口能夠被多實現,這就是多繼承改良後的結果。java將多繼承機制經過多現實來體現。
6:一個類在繼承另外一個類的同時,還能夠實現多個接口。因此接口的出現避免了單繼承的侷限性。還能夠將類進行功能的擴展。
7:其實java中是有多繼承的。接口與接口之間存在着繼承關係,接口能夠多繼承接口。
接口都用於設計上,設計上的特色:(能夠理解主板上提供的接口)
1:接口是對外提供的規則。
2:接口是功能的擴展。
3:接口的出現下降了耦合性。
抽象類與接口:
抽象類:通常用於描述一個體系單元,將一組共性內容進行抽取,特色:能夠在類中定義抽象內容讓子類實現,能夠定義非抽象內容讓子類直接使用。它裏面定義的都是一些體系中的基本內容。
接口:通常用於定義對象的擴展功能,是在繼承以外還需這個對象具有的一些功能。
抽象類和接口的共性:都是不斷向上抽取的結果。
抽象類和接口的區別:
1:抽象類只能被繼承,並且只能單繼承。
接口須要被實現,並且能夠多實現。
2:抽象類中能夠定義非抽象方法,子類能夠直接繼承使用。
接口中都有抽象方法,須要子類去實現。
3:抽象類使用的是 is a 關係。
接口使用的 like a 關係。
4:抽象類的成員修飾符能夠自定義。
接口中的成員修飾符是固定的。全都是public的。
在開發以前,先定義規則,A和B分別開發,A負責實現這個規則,B負責使用這個規則。至於A是如何對規則具體實現的,B是不須要知道的。這樣這個接口的出現就下降了A和B直接耦合性。