Java基礎八 一、子父類中構造函數的特點 1.1 為什麼在子類構造對象時,發現,訪問子類構造函數時,父類也運行了呢? 原因是:在子類的構造函數中第一行有一個預設的隱式語句。 super(); 構造方法中其實還有一句return; 子類的實例化過程:子類中所有的構造函數預設都會訪問父類中的空參數的構 ...
Java基礎八
一、子父類中構造函數的特點
1.1 為什麼在子類構造對象時,發現,訪問子類構造函數時,父類也運行了呢?
原因是:在子類的構造函數中第一行有一個預設的隱式語句。 super();
構造方法中其實還有一句return;
子類的實例化過程:子類中所有的構造函數預設都會訪問父類中的空參數的構造函數。
說明:
其實只要記住子類構造函數中預設有一句super();即可,所以當父類為有參時,super也應該有參。
構造函數不能覆蓋,因為名字都不一樣。
構造函數也不能繼承過來,所以我們有super。
super只是java給你省了,不是這句話不需要,其實我們寫子類構造函數的時候都寫上。
1.2 為什麼子類實例化的時候要訪問父類中的構造函數呢?
那是因為子類繼承了父類,獲取到了父類中內容(屬性),所以在使用父類內容之前,
要先看父類是如何對自己的內容進行初始化的。
所以子類在構造對象時,必須訪問父類中的構造函數。
為什麼完成這個必須的動作,就在子類的構造函數中加入了super()語句。
如果父類中沒有定義空參數構造函數,那麼子類的構造函數必須用super明確要調用
父類中哪個構造函數。
但是可以保證的是,子類中肯定會有其他的構造函數訪問父類的構造函數。
註意:supre語句必須要定義在子類構造函數的第一行。因為父類的初始化動作要先完成。
同時子類構造函數中如果使用this調用了本類構造函數時,
那麼super就沒有了,因為super和this都只能定義第一行。所以只能有一個。
子類中總有一個構造函數會調用父類構造函數。
所有的類都繼承了object類,所有的類都會有super();
構造函數的許可權和本類一樣。本類是public,構造函數也是預設public。
1.3 子父類變數初始化的問題
先執行子類構造器,然後執行父類構造器完成變數初始化,然後是子類的變數的顯示初始化。
父類的構造函數完成初始化,然後再是子類函數的初始化。
子類有show方法,在父類構造函數的時候show是運行子類的,因為是子類的對象。
1 class Fu 2 3 { 4 5 Fu() 6 7 { 8 9 super(); 10 11 show(); 12 13 return; 14 15 } 16 17 18 19 void show() 20 21 { 22 23 System.out.println("fu show"); 24 25 } 26 27 } 28 29 class Zi extends Fu 30 31 { 32 33 int num = 8; 34 35 Zi() 36 37 { 38 39 super(); 40 41 //-->通過super初始化父類內容時,子類的成員變數並未顯示初始化。等super()父類初始化完畢後, 42 43 //才進行子類的成員變數顯示初始化。 44 45 46 47 System.out.println("zi cons run...."+num); 48 49 return; 50 51 } 52 53 void show() 54 55 { 56 57 System.out.println("zi show..."+num); 58 59 } 60 61 } 62 63 class ExtendsDemo5 64 65 { 66 67 public static void main(String[] args) 68 69 { 70 71 Zi z = new Zi(); 72 73 z.show(); 74 75 } 76 77 }
實例化圖解
1.4一個對象實例化過程:
一個對象實例化過程:
Person p = new Person();
1,JVM會讀取指定的路徑下的Person.class文件,並載入進記憶體,
並會先載入Person的父類(如果有直接的父類的情況下).
2,在堆記憶體中的開闢空間,分配地址。
3,併在對象空間中,對對象中的屬性進行預設初始化。
4,調用對應的構造函數進行初始化。
5,在構造函數中,第一行會先到調用父類中構造函數進行初始化。
6,父類初始化完畢後,在對子類的屬性進行顯示初始化。
7,在進行子類構造函數的特定初始化。
8,初始化完畢後,將地址值賦值給引用變數.
先預設初始化,再構造初始化,再顯示初始化
二、final關鍵字
2.1 繼承弊端
打破封裝性
解決方法:在類前加final,不讓你繼承
2.2 final功能
final關鍵字:
1,final是一個修飾符,可以修飾類,方法,變數。
2,final修飾的類不可以被繼承。
3,final修飾的方法不可以被覆蓋。
4,final修飾的變數是一個常量,只能賦值一次。
為什麼要用final修飾變數。其實在程式如果一個數據是固定的,
那麼直接使用這個數據就可以了,但是這樣閱讀性差,所以它該數據起個名稱。
而且這個變數名稱的值不能變化,所以加上final固定。
寫法規範:常量所有字母都大寫,多個單詞,中間用_連接。
被final修飾的就成了最終的,肯定就不能被繼承了。
三、抽象類
抽象類:
抽象:籠統,模糊,看不懂!不具體。
特點:
1,方法只有聲明沒有實現時,該方法就是抽象方法,需要被abstract修飾。
抽象方法必須定義在抽象類中。該類必須也被abstract修飾。
2,抽象類不可以被實例化。為什麼?因為調用抽象方法沒意義。
3,抽象類必須有其子類覆蓋了所有的抽象方法後,該子類才可以實例化。
否則,這個子類還是抽象類。
1,抽象類中有構造函數嗎?
有,用於給子類對象進行初始化。
2,抽象類可以不定義抽象方法嗎?
可以的。 但是很少見,目的就是不讓該類創建對象。AWT的適配器對象就是這種類。
通常這個類中的方法有方法體,但是卻沒有內容。
abstract class Demo
{
void show1()
{}
void show2()
{}
}
3,抽象關鍵字不可以和那些關鍵字共存?
private 不行
static 不行
final 不行
4,抽象類和一般類的異同點。
相同點:
抽象類和一般類都是用來描述事物的,都在內部定了成員。
不同:
1,一般類有足夠的信息描述事物。
抽象類描述事物的信息有可能不足。
2,一般類中不能定義抽象方法,只能定非抽象方法。
抽象類中可定義抽象方法,同時也可以定義非抽象方法。
3,一般類可以被實例化。
抽象類不可以被實例化。
5,抽象類一定是個父類嗎?
是的。因為需要子類覆蓋其方法後才可以對子類實例化。