黑馬程序員——繼承

----------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO開發S</a>、<a href="http://edu.csdn.net"target="blank">.Net培訓</a>、期待與您交流! ----------------------
3.8 繼承

3.8.1繼承的概述

1、繼承:Java繼承是使用已存在的類的定義作爲基礎建立新類的技術,新類的定義可以增加新的數據或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。

2、繼承的優點

     ①、提高了代碼的複用性

     ②、讓類與類之間產生了關係,有了這關係,纔有了多態的特性

       注意:千萬別因爲要獲取其他類的功能,簡化代碼而繼承,必須是類與類之間有所屬關係纔可以繼承。

3、父類,也稱爲基類,或超類

4、 聚集關係:關聯的一種形式,代表兩個類之間的整體 / 局部關係。聚集暗示着整體在概念上處於比局部更高的一個級別,而關聯暗示兩個類在概念上位於相同的級別。

       有兩種特殊聚集:共享聚集和組合聚集。

l共享聚集:它的“部分”對象可以是多個任意“整體”對象的一部分

l組合聚集:整體擁有各部分,部分與整體共存。

3.8.2繼承的特點

1、java語言:只支持單繼承,不支持多繼承,因爲多繼承容易帶來安全隱患:當多個父類中定義相同功能,而功能的內容不同,子類不確定要運行哪一個但是java保留了這種機制,並以另一種體現形式來完成表示,多實現

2、java支持多層繼承,也就是一個繼承體系。如何使用一個繼承體系中的功能?想要使用體系,先查閱體系父類的描述,因爲父類定義了該體系的共性功能,通過了解共性功能,就可以知道該體系的基本功能。在具體調用時,要創建最子類對象,其原因是父類有可能創建不了對象,另外創建子類可以使用更多的功能。

3、子父類出現,類成員的特點:

    ⑴、變量:如果子父類中出現非私有的同名成員變量時,子類要訪問本類中的變量時用this,子類要訪問父類中的變量時用super。他們倆的用法幾乎一致,只是倆代表的引用不同

    ⑵、函數:當子類出現和父類一模一樣的函數時,子類對象調用該函數會運行子類函數的內容,如同父類的函數被覆蓋了一樣,也叫重寫或覆蓋。

    當子類繼承了父類,沿襲了父類的功能,到子類中,但是子類雖具備該功能,但是功能的內容和父類不一致,這時,只需覆蓋父類功能,保留父類的功能定義,並重寫功能內容。

通過函數的複寫可以提高擴展性

    覆蓋注意事項:

     1)、子類的權限必須大於等於父類的權限,纔可以覆蓋。

     2)、靜態只能覆蓋靜態

     3)、重載只看同名函數的參數列表,而重寫的子父類方法必須一模一樣

    ⑶、構造函數:

    子父類的構造函數是不可能一樣的,因爲構造函數的函數名與類名一致。在對子類對象進行初始化時,父類的構造函數也會運行。其原因是在子類構造函數默認的第一行有一條隱式的語句super(注意當第一行是this(),就沒有super()),super會訪問父類中空參數的構造函數。

    爲什麼子類一定要訪問父類的構造函數?因爲父類中的數據子類可以直接獲取,所以子類對象在建立時,需要先查看父類是如何對這些數據進行初始化的的,所以子類在對象初始化時,要先訪問父類的構造函數。如果要訪問父類中指定構造函數,可以通過手動定義super語句來。

3.8.3 super關鍵字

   1、應用

   ⑴、在子類的構造方法內部引用父類的構造方法,如果要引用super的話,必須把super放在函數的首位。

class Base {
Base() {
System.out.println("Base");
}
}
public class Checket extends Base {
Checket() {
super();//調用父類的構造方法,一定要放在方法的首個語句
System.out.println("Checket");
}
public static void main(String argv[]) {
Checket c = new Checket();
}
}

   ⑵、在子類中調用父類中的成員方法或成員變量

class Country {
String name;
void value() {
name = "China";
}
}
class City extends Country {
String name;
void value() {
name = "Hufei";
super.value();//不調用此方法時,super.name返回的是父類的成員變量的值null
System.out.println(name);
System.out.println(super.name);
}
public static void main(String[] args) {
City c=new City();
c.value();
}
}

   ⑶、super直接傳遞參數

class Fu{
int num;
Fu(int num){
System.out.println("fu run"+"  "+num);
}
void show(){
System.out.println("fu show");
}
}
class Zi extends Fu{
Zi(){
//super();
super(4);// 傳遞參數
System.out.println("zi run");
}
void show(){
System.out.println("zi show");
}
}

  2、注意:

     ⑴、super語句必須放在子類構造函數的第一行

     ⑵、super和this都只能定義在第一行,所以只能定義一個。

     ⑶、通過super初始化父類內容時,子類的成員變量並未顯示初始化,等super()父類完畢後,才進行成員變量顯示初始化

3.8.4實例化過程

   1、子類的實例化過程:

    子類的所有的構造函數,默認都會訪問父類中的空參數的構造函數。因爲子類每一個構造函數的第一行都有一句隱式的super();當父類中沒有空參數的構造函數時,子類必須手動通過super語句形式來指定要訪問的父類中的構造函數。當然,子類的構造函數第一行也可以手動指定this語句來訪問本類中的構造函數,子類中至少會有一個構造函數會訪問父類中的構造函數

   2、對象實例化過程——以Person p = new Person();爲例

lJvm會讀取指定路徑下的Person.class文件,並加載進內存,並會先加載Person的父類

l在堆內存中開闢空間,分配地址。

l在對象空間中,對對象中的屬性進行默認初始化

l調用對應的構造函數進行初始化

l在構造函數中,第一行會先到調用父類中構造函數進行初始化

l父類初始化完畢後,再對子類的屬性進行顯示初始化

l在進行子類構造函數的特定初始化

l完畢後,將地址值賦給引用變量

3.8.6 final關鍵字

   1、final修飾的類不可以繼承

   2、final修飾的方法不可以覆蓋

   3、final修飾的變量是一個常量,只能賦值一次,且只固定顯示化賦值

    4、注意:類變量只有在final的修飾下,值纔會固定,否則可以修改,static只能說明該值被共享,但不規定是固定的。

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS開發</a>、<a href="http://edu.csdn.net"target="blank">.Net培訓</a>、期待與您交流! ----------------------

詳細請查看:<ahref="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>

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