繼承、抽象、子類實例化總結day2

---------------------- android培訓java培訓、期待與您交流! ----------------------

 每天總結一點,進步一點點:day -2

一:繼承的優點?
1.提高了代碼的複用性
2.讓類與類之間產生了關係,有了這個關係,纔有了多態的特性。

注意:千萬不要爲了獲取其他類的功能,簡化代碼而繼承,必須是類與類之間有所屬關係纔可以繼承。所屬關係 is a 。
  java中只支持單繼承,不支持多繼承,因爲多繼承容易帶來安全隱患(當多個父類中定義了相同的功能,當功能內容不同時,
  子類對象不確定要運行哪一個),但支持多層繼承,但java保留這種機制,java只在接口與接口之間可以多實現。
  可以理解爲一個孩子只能有一個親生父親,一個孩子可以任多個乾爹,那就是實現多個接口了,呵呵

二:如何使用一個繼承體系中的功能呢?

java支持多層繼承。也就是一個繼承體系。
如果要使用體系,先查閱體系父類的描述,因爲父類的功能定義的是該體系中的共性功能,通過了解共性功能,就可以知道該體系的基本
功能,那麼這個體系基本上可以使用了。那麼在具體調用時,要創建最子類的對象,爲什麼呢?
1.因爲有可能父類不能創建對象,如抽象類和接口
2.創建子類對象可以使用更多的功能,包括父類基本的也包括子類特有的。

簡單一句話:查閱父類功能,創建子類對象使用功能。

三:什麼是聚集?
聚集:has a,又分爲聚合和組合。

聚合:學生和班級,球員和球隊,球員是球隊中的一個,球隊中有球員。球隊中少了一個球員可以

組合:手是人身體的一部分,心臟是人身體一部分,事物的練習更緊密了。身體少一部分是不可以的。

四:this和super區別?
this:代表本類對象的引用,區分成員變量和局部變量同名,代表this所在函數所屬對象的引用,那個對象調用this所在的函數,this就代表那個對象
  即本類功能內部調用本類對象用this 例:public boolean compare(Person p) return this.age==p.age;
  構造函數之間的調用必須用this,成員變量要麼用對象.Field或類名.Field調用。即若在一個類中可以省略this或者類名
  構造函數調用this必須放在第一行,因爲初始化動作要先執行。
super:代表父類對象的引用,子類Filed與父類同名,或子類的方法覆蓋了父類方法,這時如果子類要調用父類中的Field或者方法,必須用super,因爲
  super是父類的引用,一般情況下不會出現super.Filed 的情況,因爲封裝的時候都會將Field隱藏起來,對外僅提供sett or gett方法訪問,即使不隱藏,
  子類繼承父類的時候也具備了Field屬性,那麼子類沒有必要再重新定義了一個重名的Filed了。
  子類實例化的時候如果沒有顯示指定調用父類的構造函數,會隱式的使用super調用父類空參數的構造函數,super(),並一直向上追溯到 Object 類。super也必須
  放在構造函數的第一行,因爲子類要使用父類的數據,他要先看父類是怎樣對這個數據初始化的,即初始化動作要先執行

  即加載zi.class文件之前必須先加載fu.class文件,沒父何談子呢,在方法區中,子類一般持有兩個引用,this和super


注意:this與super不能同時出現在同一個“構造函數”中,因爲他們都必須出現在子類構造函數的第一行,初始化動作必須先執行。

四:什麼時候用覆蓋 override?
當子類雖具備該功能,但是功能的內容卻和父類不一致,這時子類沒有必要定義新功能,而是使用覆蓋保留父類的功能定義,並重寫功能內容。
簡單一句話:子類沿襲父類功能,定義子類特有內容。
1.子類覆蓋父類,必須保證子類權限大於等於父類權限,纔可以覆蓋,否則編譯失敗
例:fu  : void show()   zi: private void show();  編譯失敗
    fu  : private void show()   zi :  void show(); 可以,子類不知道父類的show() 相當於子類重寫定義了一個show()方法

2.靜態只能覆蓋靜態。
3.注意:
重載:只看同名函數的參數列表
覆蓋:字符類方法要一模一樣。
例:fu : int show(){return 1;}
    zi : void show(){}
 編譯失敗,沒覆蓋,即使創建子類對象了,相當於子類也有了一個int show(){return 1;},子類對象不知道具體要運行哪一個

構造函數不能覆蓋,因爲函數名都不一樣。


五:子類的實例化過程?
在對子類對象進行初始化時,父類的構造函數也會運行,
那是因爲子類的構造函數默認第一行有一條隱式的語句 super();
super() :會訪問父類中空參數的構造函數。而且子類中所有的構造函數默認第一行都是super();

爲什麼默認的隱式語句是super(),因爲父類中默認也有一條隱式super()。如果父類中定義了顯示的super(int x),
那麼子類中的構造函數也必須顯示的指定super(x),否則會出現變異編譯失敗。

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

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

父類中也有一個super()訪問Object類的構造函數。

六:final關鍵字?
final 可以修飾類、方法、變量。不能與 abstract 連用
final 修飾的類不可以被繼承。如果不希望類被繼承,則用 final class Demo
final 修飾的方法不可以被覆蓋
  如果一個類中有幾個方法是調用底層的,不希望複寫, final void show1(){} final void show2(){}

final 修飾的變量是一個常量。只能被賦值一次。既可以修飾成員變量又可以修飾局部變量。
  即在描述事物時,一些數據的出現值是固定的,那麼這時爲了增強閱讀性,都給這個值起個名字,方便與閱讀。
  而這個值不需要被改變,加final修飾。經常與static連用即public static final 即全局常量。
  final float PI=3.14f;
  
重點:內部類定義在類中的局部位置上時只能訪問被final修飾的局部變量。

七:抽象?
當多個類中出現相同功能,但功能主體不同,
這時可以進行向上抽取,只抽取功能定義,而不抽取功能主體。這個方法可以用abstract 標識
1.抽象方法必須放在抽象類中。
2.抽象方法和抽象類都必須被abstract關鍵字修飾
3.抽象類不可以用new 創建對象,因爲調用抽象方法沒意義,但可以通過其子類實例化
4.抽象類中的方法要被使用,必須由子類複寫其所有的抽象方法後,建立子類對象調用
 如果子類只覆蓋了部分抽象方法,那麼該子類還是一個抽象類。
5.抽象類可以強制子類去做一些事情。

抽象類和一般類沒有太大的不同,該如何描述事物,就如何描述事物,只不過該事物出現了一些看不懂的東西。
這些不確定的部分,也是該事物的功能,需要明出現,但是無法定義主體,通過抽象方法來表示。

抽象類比一般類多了抽象函數,抽象類中也可以不定義抽象方法,不讓該類創建對象,必須子類實例化。
抽象類不能實例化。但具備構造方法。

抽象方法不能有方法主體,即public abstract void show(){}是錯誤的

注意:
     abstract 不能用於修飾Filed(成員變量),也不能用於修飾局部變量,即沒有抽象變量,抽象Field一說
  abstract 也不能用於修飾構造函數,沒有抽象構造函數。
  當用 static 修飾一個方法時,這個方法屬於類本身,即通過類就可以調用該方法,如果該方法被定義成
  一個抽象方法(調用了一個沒有方法體的方法),
  編譯失敗,錯誤: 非法的修飾符組合: abstract和static:public abstract static void show();
  即沒有所謂的類抽象方法。

  abstract 修飾的方法必須被其子類重寫纔有意義,否則這個方法永遠不會有方法體, 因此abstract不能定義
  爲private訪問權限,即private和abstract不能同時使用。
 錯誤: 非法的修飾符組合: abstract和private
 private abstract void show();

 

---------------------- android培訓java培訓、期待與您交流! ----------------------詳細請查看:http://edu.csdn.net/heima 

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