----------------- <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>