Java面向對象編程作為一種編程思想,有三大特性,封裝,繼承,多態。對於一個類而言,如何封裝呢?繼承是父類和子類的關系,繼承關系如何實現的呢?父類和子類繼承時的方法體是怎么樣的關系呢?多態的英文多個類之間的關系,類有不同的行為和屬性,其他類也有這樣的方法和屬性,就實現了多態的關系,不同類的多態實現是怎么樣實現的呢?
一:面向對象編程三大特性
面向對象編程是利用類和對象編程的一種思想。萬物可歸類,類是對於世界事物的高度抽象,不同的事物之間有不同的關系,一個類自身與外界的封裝關系,一個父類和子類的繼承關系,一個類和多個類的多態關系。萬物皆對象,對象是具體的世界事物,面向對象的三大特征封裝,繼承,多態,封裝,封裝說明一個類行為和屬性與其他類的關系,低耦合,高內聚;繼承是父類和子類的關系,多態說的是類與類的關系。
封裝
-
什么是封裝
把客觀事物封裝成抽象的類,並且把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。也就是說抽象數據類型對數據信息以及對數據的操作進行打包,將其變成一個不可分割的實體,在這個實體內部,我們對數據進行隱藏和保密,只留下一些接口供外部調用。簡單的說,一個類就是一個封裝了數據以及操作這些數據的代碼的邏輯實體。在一個對象內部,某些代碼或某些數據可以是私有的,不能被外界訪問。通過這種方式,對象對內部數據提供了不同級別的保護,以防止程序中無關的部分意外的改變或錯誤的使用了對象的私有部分。
封裝隱藏了類的內部實現機制,可以在不影響使用的情況下改變類的內部結構,同時也保護了數據。對外界而已它的內部細節是隱藏的,暴露給外界的只是它的訪問方法。
就好比一個烤面包機,我們把面包(數據)放進去,按下開關,過了一會,它就會自動彈出烤好的面包(處理后的信息),而這個過程是怎么烤的(對數據的操作),我們是不需要知道的,
- 1
-
需要為什么封裝
隱藏一個類中不需要對外提供的實現細節;屬性的封裝:使用者只能通過事先定制好的方法來訪問數據,可以方便地加入邏輯控制,限制對屬性的不合理操作;
方法的封裝:使用者按照既定的方式調用方法,不必關心方法的內部實現,便於使用;便於修改,增強代碼的可維護性;
- 如何封裝
利用權限修飾符來描述方法體或屬性.private修飾的屬性或方法為該類所特有,在任何其他類中都不能直接訪問;默認修飾的屬性或方法具有包訪問特性,同一個包中的其他類可以訪問;保護修飾的屬性或方法在同一個中的其他類可以訪問,同時對於不在同一個包中的子類中也可以訪問;公共修飾的屬性或方法外部類中都可以直接訪問。
封裝類似於黑箱操作,其設計要求是低耦合,高內聚。一個具體復雜的對象有很多的屬性和方法,有些需要公開,有些不需要公開,就好比一個具體的人的信息,有些是公眾,有些是私人的,而有些是protecred,別人問到的時候對於怎么樣的信息都有不同的態度。根據與這個人的關系來回答問題,封裝的結果是輸出結果,不問過程,其中,公共是可以被任何變量訪問的,私人是該類私有的,受保護類是受保護的,可以被該類所述的包內的所有的其他類訪問,其子類也可以訪問。
比如我們將一個房子看做是一個對象,里面的漂亮的裝飾,如沙發,電視劇,空調,茶桌等等都是該房子的私有屬性,但是如果我們沒有那些牆遮擋,是不是別人就會一覽無余呢?沒有一點兒隱私!就是存在那個遮擋的牆,我們既能夠有自己的隱私而且我們可以隨意的更改里面的擺設而不會影響到其他的。但是如果沒有門窗,一個包裹的嚴嚴實實的黑盒子,又有什么存在的意義呢?所以通過門窗別人也能夠看到里面的風景。所以說門窗就是房子對象留給外界訪問的接口。
2.繼承
- 什么是繼承
繼承是從已有的類中派生出新的類,新的類能吸收已有類的數據屬性和行為,並能擴展新的能力。
在本職上是特殊——一般的關系,即常說的is-a關系。子類繼承父類,表明子類是一種特殊的父類,並且具有父類所不具有的一些屬性或方法。從多種實現類中抽象出一個基類,使其具備多種實現類的共同特性 ,當實現類用extends關鍵字繼承了基類(父類)后,實現類就具備了這些相同的屬性。
繼承的類叫做子類(派生類或者超類),被繼承的類叫做父類(或者基類)。
比如從貓類、狗類、虎類中可以抽象出一個動物類,具有和貓、狗、虎類的共同特性(吃、跑、叫等)。
-
如何實現繼承: Java通過extends關鍵字來實現繼承,父類中通過private定義的變量和方法不會被繼承,不能在子類中直接操作父類通過private定義的變量以及方法。
繼承的優點: 繼承避免了對一般類和特殊類之間共同特征進行的重復描述,通過繼承可以清晰地表達每一項共同特征所適應的概念范圍——在一般類中定義的屬性和操作適應於這個類本身以及它以下的每一層特殊類的全部對象。運用繼承原則使得系統模型比較簡練也比較清晰。
- 繼承有哪些原則
成員變量的繼承原則 具體的原則如下:- [u ] 能夠繼承父類的public和protected成員變量;不能夠繼承父類的private成員變量;
- [u ] 對於父類的包訪問權限成員變量,如果子類和父類在同一個包下,則子類能夠繼承;否則,子類不能夠繼承;
- [y ] 對於子類可以繼承的父類成員變量,如果在子類中出現了同名稱的成員變量,則會發生隱藏現象,即子類的成員變量會屏蔽掉父類的同名成員變量。如果要在子類中訪問父類中同名成員變量,需要使用super關鍵字來進行引用。
1.的方法重寫
子類如果對繼承的父類的方法不滿意(不適合),可以自己編寫繼承的方法,這種方式就稱為方法的重寫。通過重寫父類的方法,可以用自身的行為代替父類的行為。當調用方法時會優先調用子類的方法。重寫要注意:a,返回值類型b,方法名c,參數類型及個數
都要與父類繼承的方法相同,才叫方法的重寫。
重載和重寫的區別:
方法重載:同在一個類中處理不同數據的多個相同方法名的多態手段
方法重寫:相對繼承而言,子類中對父類已經存在的方法進行區別化的修改
2。初始化繼承順序
父類的構造器調用以及初始化過程一定在子類的前面
如圖1所示,初始化父類再初始化子類
2,先執行初始化對象中屬性,再執行構造方法中的初始化。
基於上面兩點,我們就知道實例化一個子類,JAVA程序的執行順序是:
父類對象屬性初始化---->父類對象構造方法---->子類對象屬性初始化- >類子對象構造方法
下面有個形象的圖:
繼承實例:
/
1. 我是父類super
2. 我是子類sub
3. 先打印的是父類里面的在打印的子類里面
4. 從這個可以看出是先調用父類的構造方法創建父類對象再來調用子類里面的構造方法
*/
class Super{
public Super(){
System.out.println("我是父類super");
}
}
class Sub extends Super{
public Sub(){
System.out.println("我是子類sub");
}
}
public class InstanceDemo {
public static void main(String[] args) {
new Sub();
}
}
運行結果:
3.多態
Java面向對象編程之多態
相比於封裝和繼承,Java多態是三大特性中比較難的一個,封裝和繼承最后歸結於多態,多態指的是類和類的關系,兩個類由繼承關系,存在有方法的重寫,故而可以在調用時有父類引用指向子類對象。自己對於多態的理解還不夠深刻,故而轉載了一篇關於多態比較好的文章。
public class main { /
@param args / public static void main(String[] args) { //分別將animal實例化成三種動物, Animal an = new Dog(); an.cry();//根據每種動物自身的方法,自動選擇內容 an = new Cat(); an.cry(); an = new UnknowAnimal(); an.cry(); } } //基本類,包含一個基本方法 class Animal{ public void cry(){ System.out.println("我不知道自己是什么動物。"); } } //聲明子類,繼承基本類,但有自己的方法 //實例化后優先使用自身的方法。 class Dog extends Animal{ public void cry(){ System.out.println("這是一條狗。"); } } class Cat extends Animal{ public void cry(){ System.out.println("這是一只貓。"); } } //這個子類自身沒定義方法,實例化后會使用從父類繼承來的方法 class UnknowAnimal extends Animal{ }
運行結果如下: