1.封裝性
增強安全性和簡化編程,使用者不必瞭解具體的實現細節。
隱藏對象的屬性和實現細節,僅對外公開接口來對程序中屬性的讀和修改。
封裝的基本做法: 把所有的屬性私有化,對每個屬性提供getter和setter方法,在開發的時候經常要對已經編寫的類進行測試,所以有的時候還需重寫toString方法。
2.繼承性
用extends關鍵字實現繼承,主要利於代碼的複用。
繼承而得到的類稱爲子類,被繼承的類稱爲父類。子類是父類的擴展,獲得父類的全部屬性和方法,除了父類中構造方法和private的成員變量和方法。一個類若無指定父類則默認繼承於Object。
父類普通方法:使用override重寫,若是抽象方法,子類必須全部實現他們,否則就得聲明自己爲抽象類。
父類構造方法:這個是不能繼承的,其實它是被子類構造方法隱士調用的。生成子類對象時,會默認先調用父類不帶參數的構造方法生成父類對象(若無就在子類構造方法中用super顯示調用有參構造方法),再調用子類構造方法才生成子類對象。
只能單繼承,因爲如果繼承了A和B,若他們有同名的方法你就不知道要調用哪一個了,但我們可以使用接口實現多重繼承,因爲接口裏面的方法都是抽象的,沒有實現,所以隨便調哪個都無所謂了。
interface A{}
interface B{}
interface C extends A,B{}
class C1 implements C{}
3.多態性
在程序中定義的某個引用變量具體所指向的類型和調用的方法在編碼時並不能確定,而只有在運行的時候才能確定。這樣能屏蔽不同子類對象之間的差異,寫出通用的代碼以適應需求的不斷變化。
- 編譯時多態:重載
- 運行時多態:繼承 重寫
簡單說多態就是單繼承多實現,使用父類引用指向子類對象,再調用某一父類中的方法時,不同子類會表現出不同結果,保證了擴展性。他還具有可替代性,簡化性。
這裏需要注意的是,假設Apple爲Fruit子類,Fruit f=new Apple();
父類引用子類對象時調用誰的成員方法由被引用對象的類型(Apple)決定,而不是引用變量的類型(Fruit)決定,但是這個方法必須是父類中定義過的,這樣纔會調用子類中的方法,若不是重寫的方法,就會向上找,優先級如下:(重點)
this.X(obj)—>super.X(obj)—>this.X(super(obj))—>super.X(super(obj))
想必大家對此還比較模糊吧,說個例子就行了。
class A {
public String show(D obj){
return ("A and D");
}
public String show(A obj){
return ("A and A");
}
}
class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
class C extends B{}
class D extends B{}
題目
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println(a2.show(b)); ④
System.out.println(a2.show(c)); ⑤
System.out.println(a2.show(d)); ⑥
System.out.println(b.show(b)); ⑦
System.out.println(b.show(c)); ⑧
System.out.println(b.show(d)); ⑨
答案
④ B and A
⑤ B and A
⑥ A and D
⑦ B and B
⑧ B and B
⑨ A and D
我就出了了幾個繞一點的,a2.show(b),因爲a2是父類引用指向子類的,按剛纔說的優先級來解釋,這裏this代表A,先this.show(B)沒有這個方法,則super.show(B),A沒有父類,則this.show(super(B)),有了,於是輸出A and A,一看不對,其實是這樣的,我前面加粗了一句話,再仔細品味下吧,這裏父類有的方法子類重寫了,所以我得調用B的show(A),輸出B and A