標籤:
摘自翁愷老師的mooc
對理解繼承來說,最重要的事情是,知道哪些東西被繼承了,或者說,子類從父類那裡得到了什麼。答案是:所有的東西,所有的父類的成員,包括變數和方法,都成為了子類的成員,除了構造方法。構造方法是父類所專屬的,因為它們的名字就是類的名字,所以父類的構造方法在子類中不存在。除此之外,子類繼承得到了父類所有的成員。
但是得到不等於可以隨便使用。每個成員有不同的訪問屬性,子類繼承得到了父類所有的成員,但是不同的訪問屬性使得子類在使用這些成員時有所不同:有些父類的成員直接成為子類的對外的介面,有些則被深深地隱藏起來,即使子類自己也不能直接存取。下表列出了不同訪問屬性的父類成員在子類中的訪問屬性。
父類成員訪問屬性 |
在父類中的含義 |
在子類中的含義 |
public |
對所有人開放 |
對所有人開放 |
protected |
只有包內其它類、自己和子類可以訪問 |
只有包內其它類、自己和子類可以訪問 |
預設 |
只有包內其它類可以訪問 |
如果子類與父類在同一個包內:只有包內其它類可以訪問 否則:相當於private,不能訪問 |
private |
只有自己可以訪問 |
不能訪問 |
public的成員直接成為子類的public的成員,protected的成員也直接成為子類的protected的成員。Java的protected的意思是包內和子類可訪問,所以它比預設的訪問屬性要寬一些。而對於父類的預設的未定義訪問屬性的成員來說,他們是在父類所在的包內可見,如果子類不屬於父類的包,那麼在子類裡面,這些預設屬性的成員和private的成員是一樣的:不可見。父類的private的成員在子類裡仍然是存在的,只是子類中不能直接存取。我們不可以在子類中重新定義繼承得到的成員的訪問屬性。如果我們試圖重新定義一個在父類中已經存在的私人成員變數,那麼我們是在定義一個與父類的成員變數完全無關的變數,在子類中我們可以訪問這個定義在子類中的變數,在父類的方法中訪問父類的那個。儘管它們同名但是互不影響。如果我們試圖定義一個父類中已經存在的非私人成員變數,編譯器會給我們一個編譯錯誤。
在構造一個子類的對象時,父類的構造方法也是會被調用的,而且父類的構造方法在子類的構造方法之前被調用。在程式運行過程中,子類對象的一部分空間存放的是 父類對象。因為子類從父類得到繼承,在子類對象初始化過程中可能會使用到父類的成員。所以父類的空間正是要先被初始化的,然後子類的空間才得到初始化。在 這個過程中,如果父類的構造方法需要參數,如何傳遞參數就很重要了。
java子類與父類的關係