首頁  >  文章  >  Java  >  Java封裝、繼承、多型三大特徵的理解

Java封裝、繼承、多型三大特徵的理解

高洛峰
高洛峰原創
2017-01-19 14:08:491797瀏覽

首先先簡單的說一下其3大特性的定義:

封裝:隱藏物件的屬性和實作細節,僅對外公開介面,控制在程式中屬性的讀取和修改的存取層級。將抽象得到的數據和行為(或功能)結合,形成一個有機的整體,也就是將數據與操作數據的源代碼進行有機的結合,形成“類”,其中數據和函數都是類的成員。封裝的目的是增強安全性和簡化編程,使用者不必了解具體的實作細節,而只是要透過外部接口,一特定的存取權限來使用類別的成員。封裝的基本要求是: 把所有的屬性私有化,對每個屬性提供getter和setter方法,如果有一個帶參的構造函數的話,那一定要寫一個不帶參的構造函數。在開發的時候經常要對已經寫好的類別進行測試,所以在有的時候還有重寫toString方法,但這不是必須的。

繼承:透過繼承實現程式碼重複使用。 Java中所有的類別都是透過直接或間接地繼承java.lang.Object類別得到的。繼承而得到的類別稱為子類,被繼承的類別稱為父類別。子類別不能繼承父類別中存取權限為private的成員變數和方法。子類別可以重寫父類別的方法,及命名與父類別同名的成員變數。但Java不支援多重繼承,即一個類別從多個超類別派生的能力。在開發中盡量減少繼承關係,這樣做是為了把程式的耦合度降低。

多態:多態又分為設計時多態性和運行時多態,例如重載又被稱為設計時多態性,而對於覆蓋或繼承的方法,JAVA運行時系統根據調用該方法的實例的類型來決定選擇呼叫哪個方法則稱為運行時多態。總而言之,物件導向的設計的典型特點就是繼承,封裝和多態,這些特點也是物件導向之所以能如此盛行的關鍵所在。

封裝

java中類別的屬性的存取權限預設值不是private,要想隱藏該屬性的方法,就可以加private修飾符,來限制只能夠在類別的內部進行存取。

對於類別中的私有屬性,要對其給定一對方法(getXXX,setXXX())存取私有屬性,確保對私有屬性的操作和安全性。

方法的封裝,該公開的公開,該隱藏的隱藏。

java的繼承

繼承,是對有著共同特性的多類事物,進行再抽象成一個類別。

java中的繼承要使用extends關鍵字,並且java中指允許單繼承,也就是一個類別只能有一個父類別。

構造方法不能被繼承。

java方法中的覆寫

子類別中有和父類別中可存取的同名同傳回同參數清單的方法時,就會覆寫從父類別繼承來的方法。

super()關鍵字

super(),表示在子類別的建構方法呼叫父類別的建構方法時,super()也只能在建構方法中的第一句。

java中的多態

有兩種多態的機制:編譯時多態、運行時多態

1、方法的重載:重載是指同一類中有多個同名的方法,但這些方法有著不同的參數。 ,因此在編譯時就可以確定到底要呼叫哪個方法,它是一種編譯時多態。

2、方法的覆蓋:子類別可以覆蓋父類別的方法,因此同樣的方法會在父類別中與子類別中有著不同的表現形式。在java語言中,基類的引用變數不僅可以指向基類的實例對象,也可以指向子類的實例對象,同樣,接口中的引用變數也可以指向其實現類的實例對象。

public class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
} 
}
public class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
} 
}
public class C extends B{
}
public class D extends B{
}
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D(); 
System.out.println("1--" + a1.show(b));
System.out.println("2--" + a1.show(c));
System.out.println("3--" + a1.show(d));
System.out.println("4--" + a2.show(b));
System.out.println("5--" + a2.show(c));
System.out.println("6--" + a2.show(d));
System.out.println("7--" + b.show(b));
System.out.println("8--" + b.show(c));
System.out.println("9--" + b.show(d)); 
}
}
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D

當超類別物件引用變數引用子類別物件時,被引用物件的類型而不是引用變數的類型決定了呼叫誰的成員方法,但是這個被呼叫的方法必須是在超類別中定義過的,也就是說被子類別覆蓋的方法。

這我們用一個例子來說明這句話所代表的含義:a2.show(b);

這裡a2是引用變量,為A類型,它引用的是B對象,因此按照上面那句話的意思是說有B來決定呼叫誰的方法,所以a2.show(b)應該要呼叫B中的show(B obj),產生的結果應該是“B and B”,但是為什麼會與前面的運行結果產生差異呢?這裡我們忽略了後面那句話“但是這兒被呼叫的方法必須是在超類別中定義過的”,那麼show(B obj)在A類中存在嗎?根本就不存在!所以這句話在這裡不適用?那麼難道是這句話錯誤了?非也!其實這句話還隱含這句話:它還是要按照繼承鏈中呼叫方法的優先權來確認。所以它才會在A類別中找到show(A obj),同時由於B重寫了該方法所以才會呼叫B類別中的方法,否則就會呼叫A類別中的方法。

以上所述是小編給大家介紹的Java封裝、繼承、多態三大特徵的理解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對PHP中文網的支持!

更多Java封裝、繼承、多態三大特徵的理解相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn