【JavaSE】繼承與多態的理解與區別


@

抽象類的特點:

	A:抽象類和抽象方法必須用abstract關鍵字修飾
	B:抽象類中不一定有抽象方法,但是有抽象方法的類必須定義為抽象類
	C:抽象類不能實例化
		因為它不是具體的。
		抽象類有構造方法,但是不能實例化?構造方法的作用是什么呢?
		用於子類訪問父類數據的初始化
	D:抽象的子類
		a:如果不想重寫抽象方法,該子類是一個抽象類。
		b:重寫所有的抽象方法,這個時候子類是一個具體的類。

抽象類的實例化其實是靠具體的子類實現的。是多態的方式。
Animal a = new Cat();

多態其實主要用於 抽象類和其具體子類。而不是具體類和具體類之間。

抽象類和接口的區別:

A:成員區別
抽象類:
	成員變量:可以變量,也可以常量
	構造方法:有
	成員方法:可以抽象,也可以非抽象
接口:
	成員變量:只可以常量  默認public static final
	成員方法:只可以抽象  默認public abstract
	
B:關系區別
類與類
	繼承,單繼承
類與接口
	實現,單實現,多實現
接口與接口
	繼承,單繼承,多繼承
	
C:設計理念區別
抽象類 被繼承體現的是:”is a”的關系。抽象類中定義的是該繼承體系的共性功能。
接口 被實現體現的是:”like a”的關系。接口中定義的是該繼承體系的擴展功能。

為什么new子類要先執行父類構造方法

其實之前一直不明白構造函數“初始化”的含義。一直以為 “初始化”==“變量賦值”,其實初始化的內涵不是這樣的。

class Person{...}
class Student extends Person{...}

對於Student stu = new Student(),更合理的解釋是:

1, 加載class文件

	5, 父類靜態變量加載到方法區
	6, 父類靜態代碼塊初始化變量
	7, 子類靜態變量加載到方法區
	8, 子類靜態代碼塊初始化變量

2, 加載main方法在棧內存中(類被加載后,虛擬機再調用靜態方法main。類加載會先走靜態代碼塊,注定靜態代碼塊	先於main)
3, 在棧內存中開辟空間給Student stu(對象引用的空間)
4, new申請堆內存空間(對象的空間)


9, 父類變量默認初始化、顯示初始化(一般只有默認初始化,創建一個學生類時不會直接寫age=20,這樣以后每個創建的對象一開始就20歲)
10, 父類構造代碼塊初始化(如果有賦值語句)
11, 父類構造器初始化(如果有賦值語句)

12, 子類變量默認初始化、顯示初始化(一般只有默認初始化,創建一個學生類時不會直接寫age=20,這樣以后每個創建的對象一開始就20歲)
13, 子類構造代碼塊初始化(如果有賦值語句)
14, 子類構造器初始化(如果有賦值語句)

最后,把對象地址賦值給stu

詳見:

http://bbs.csdn.net/topics/380077372
http://www.jb51.net/article/37881.htm
http://bbs.csdn.net/topics/260013819

多態的弊端及解決辦法

弊端:Fu f = new Zi() f不能用子類特有方法。

解決辦法: Zi z = (Zi)f; 由於本身是子類對象,可以向下轉型會子類引用,再調用子類特有方法。

繼承和多態中成員訪問的特點總結

繼承是站在子類的角度,多態是站在父類的角度。

繼承時,子類為觀察者,發起者。不論是成員變量還是成員方法,都是遵照就近原則。
子類變量會被優先調用。
而子類方法會覆蓋父類方法。
所以,同名情況下,子類都先使用自己的。




多態中,父類為觀察者,發起者。
父類自己的變量會優先調用,而且不存在調用子類變量的情況。因為,調用子類變量說明變量名不同,說明是子類后加上去的。父類中是沒有get該變量的方法的!
父類方法會被子類方法覆蓋。
所以同名曲情況下,父類使用自己的變量,使用子類的方法。



實際開發中,使用繼承一般更多的是為了復用性,為了重寫父類方法。很少涉及變量(子類自己的)。
    使用多態一般更多的是為了可維護性,為了同一個引用調用不同子類的特有同名方法。很少涉及變量(父類自己的)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM