一.你瞭解繼承嗎?
繼承是所有OOP語言不可缺少的部分,在java中使用extends關鍵字來表示繼承關係。當創建一個類時,總是在繼承,如果沒有明確指出要繼承的類,就總是隱式地從根類Object進行繼承。比如下面這段代碼:
1 2 3 4 5 6 7 8 9 10 11 | class Person { public Person() { } } class Man extends Person { public Man() { } } |
類Man繼承於Person類,這樣一來的話,Person類稱爲父類(基類),Man類稱爲子類(導出類)。如果兩個類存在繼承關係,則子類會自動繼承父類的方法和變量,在子類中可以調用父類的方法和變量。在java中,只允許單繼承,也就是說 一個類最多隻能顯示地繼承於一個父類。但是一個類卻可以被多個類繼承,也就是說一個類可以擁有多個子類。
1.子類繼承父類的成員變量
當子類繼承了某個類之後,便可以使用父類中的成員變量,但是並不是完全繼承父類的所有成員變量。具體的原則如下:
1)能夠繼承父類的public和protected成員變量;不能夠繼承父類的private成員變量;
2)對於父類的包訪問權限成員變量,如果子類和父類在同一個包下,則子類能夠繼承;否則,子類不能夠繼承;
3)對於子類可以繼承的父類成員變量,如果在子類中出現了同名稱的成員變量,則會發生隱藏現象,即子類的成員變量會屏蔽掉父類的同名成員變量。如果要在子類中訪問父類中同名成員變量,需要使用super關鍵字來進行引用。
2.子類繼承父類的方法
同樣地,子類也並不是完全繼承父類的所有方法。
1)能夠繼承父類的public和protected成員方法;不能夠繼承父類的private成員方法;
2)對於父類的包訪問權限成員方法,如果子類和父類在同一個包下,則子類能夠繼承;否則,子類不能夠繼承;
3)對於子類可以繼承的父類成員方法,如果在子類中出現了同名稱的成員方法,則稱爲覆蓋,即子類的成員方法會覆蓋掉父類的同名成員方法。如果要在子類中訪問父類中同名成員方法,需要使用super關鍵字來進行引用。
注意:隱藏和覆蓋是不同的。隱藏是針對成員變量和靜態方法的,而覆蓋是針對普通方法的。(後面會講到)
3.構造器
子類是不能夠繼承父類的構造器,但是要注意的是,如果父類的構造器都是帶有參數的,則必須在子類的構造器中顯示地通過super關鍵字調用父類的構造器並配以適當的參數列表。如果父類有無參構造器,則在子類的構造器中用super關鍵字調用父類構造器不是必須的,如果沒有使用super關鍵字,系統會自動調用父類的無參構造器。看下面這個例子就清楚了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | class Shape { protected String name; public Shape(){ name = "shape" ; } public Shape(String name) { this .name = name; } } class Circle extends Shape { private double radius; public Circle() { radius = 0 ; } public Circle( double radius) { this .radius = radius; } public Circle( double radius,String name) { this .radius = radius; this .name = name; } } |
這樣的代碼是沒有問題的,如果把父類的無參構造器去掉,則下面的代碼必然會出錯:
改成下面這樣就行了:
4.super
super主要有兩種用法:
1)super.成員變量/super.成員方法;
2)super(parameter1,parameter2....)
第一種用法主要用來在子類中調用父類的同名成員變量或者方法;第二種主要用在子類的構造器中顯示地調用父類的構造器,要注意的是,如果是用在子類構造器中,則必須是子類構造器的第一個語句。