標籤:
Java中的物件導向
在軟體開發的學習中, 我最先接觸的開發語言就是java,但都是簡單的函數和迴圈數組的應用。說道物件導向,第一次看到這個詞的時候還是在C#的學習過程中,我記得當時PPT上霸氣的解釋,什麼是對象?萬物皆對象!夠霸氣吧,當時的物件導向思想對我來說還是挺崩潰的,什麼繼承多態啊!經過了無數的聯絡項目的書寫,終於對物件導向有了一定的理解,現在剛好在java的學習中再度重溫物件導向,那麼就將我眼中的物件導向寫出來分享給大家。
說到物件導向,我們就不得不提一下他的三大特性,繼承封裝和多態。我們先從封裝說起,什麼是封裝呢?就是把對象的屬性和操作聯合為一個整體,並且隱藏內部實現細節。這個說法比較官方,簡單的說就是把屬性用private修飾,然後建立公有方法給屬性賦值,並且在方法中控制給屬性賦值的規則。在上代碼之前給大家分享一個MyEclipse封裝的捷徑,寫好了私人屬性後按alt+shift+s出現功能表列後再按r就可以全部封裝了。
public class Student { private String stuname; private int stuage; private int stuscore;// 游標定位在這裡按快速鍵 public Student(String name,int age,int score){ this.stuname = name; this.stuage = age; this.stuscore = score; } public String getStuname() { return stuname; } public void setStuname(String stuname) { this.stuname = stuname; } public int getStuage() { return stuage; } public void setStuage(int stuage) { this.stuage = stuage; } public int getStuscore() { return stuscore; } public void setStuscore(int stuscore) { this.stuscore = stuscore; } public void say(){ System.out.println(this.stuname+"正在和大家打招呼"); }}
上面就是對一個對象的封裝,可以在set方法裡添加賦值需求。藉著上面封裝好的類,我們來看下一個特性,也就是繼承。繼承在我們日常生活中的理解就是從我們的上一輩或者上司老師那裡擷取到他的東西,而且一般是全部的東西,那麼繼承在java中是什麼意思呢?繼承就是從已有的類中派生出新的類,新的類能夠吸收已有類的資料和行為,並能擴充新的能力。一般將這個已有類稱為父類或是基類,而新的類稱為子類或衍生類別。在java繼承特性中,只能實現單繼承,也就是所有子類只能有一個父類,子類繼承父類的關鍵字是extends後面跟上類名。
下面是一個張三類,他繼承了Student類,並且覆蓋了類中的say方法:
public class StuZS extends Student { public StuZS(String name, int age, int score) { super(name, age, score); } public void say(){ System.out.println("大家好!"); }}
在這裡有幾點需要注意的地方,在父類中的私人屬性或方法在子類中是不能被繼承的,也就是說這時候StuZS類不能直接使用stuname變數,需要使用類中的set(賦值)get(取值)方法。如果在父類中有一個帶參的建構函式並且沒有無參的建構函式,那麼子類在繼承父類之後,必須有相同建構函式並且函數中的第一條語句要調用父類中的建構函式,因為當你執行個體化出子類對象的時候,會先走到父類的建構函式中執行再回到子類的建構函式中。所以如果我們的父類中有一個帶參構造,那麼基於後面的代碼的友好書寫,再加一個無參的建構函式。
現在我們知道了子類可以使用父類的方法,那麼現在問題來了,如果子類中有和父類重名的屬性或方法,那該怎麼辦呢?正子類中有和父類的重名方法我們叫做覆蓋,也就是說重寫了父類的方法,在調用的時候可以把兩個類的方法看成一種,但是其實是不一樣,在子類中通過this和super關鍵字可以區分出來,this調用的是本類的方法,super調用的是父類方法,屬性也是一樣,代碼如下:
public class StuZS extends Student { public StuZS(String name, int age, int score) { super(name, age, score); } public void say(){ System.out.println("大家好!"); } public void thisAndSuper(){ this.say(); super.say(); }}
public static void main(String[] args) { StuZS stu = new StuZS("張三", 20, 100); stu.thisAndSuper(); }
這段代碼會輸出“張三正在和大家打招呼”和“大家好!”兩句話,所以說我們在子類中可以區分出這個方法或屬性到底屬於誰。但是我們想想這樣做有什麼意義呢,我們繼承的目的就是要子類可以使用父類的屬性或方法,讓他們“不分彼此”,而父類我們一般只是將方法與屬性建立出來,所以父類say()方法中的內容時多餘的,用不到的,那麼就出現了我們的抽象方法。java中的抽象方法用abstract關鍵字修飾。在給大家看具體代碼前先看一下抽象方法的幾個特性和注意事項:
1、抽象方法所在的類必然是抽象類別,抽象類別同樣用abstract修飾
2、抽象類別中可以有普通方法和屬性
3、抽象方法不能有方法體
4、子類必須重寫父類的抽象方法,除非子類本身也是一個抽象類別
5、抽象類別不能被執行個體化
好了抽象類別和抽象方法的一些基本注意事項我們也瞭解了,那麼下面的事情就簡單了,我們只需要稍稍的修改一下代碼就OK了:
public class StuZS extends Student { public StuZS(String name, int age, int score) { super(name, age, score); } @Override public void say() { // TODO Auto-generated method stub } public void thisAndSuper(){ this.say(); super.say(); }}
這樣我們再用super調用父類方法的時候會發現報出了紅線,是不可以被調用的。
下面就是我們今天的重頭戲,也就是多態,前面的封裝和繼承幾乎都是在為多態做著準備,那麼什麼是多態呢?還是先來一段官方的解釋:多態性是指允許不同類的對象對同一訊息作出響應,多態包括參數化和包含多態性。多態性語言具有靈活、抽象、行為共用、代碼共用的優勢,很好的解決了應用程式函數同名的問題。多態既然這麼牛,那麼多態都有什麼好處呢?下面我們來一一列舉:
1.可替換性(substitutability)。多態對已存在代碼具有可替換性。例如,多態對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
2.可擴充性(extensibility)。多態對代碼具有可擴充性。增加新的子類不影響已存在類的多態性、繼承性,以及其他特性的運行和操作。實際上新加子類更容易獲得多態功能。例如,在實現了圓錐、半圓錐以及半球體的多態基礎上,很容易增添球體類的多態性。
3.介面性(interface-ability)。多態是超類通過方法簽名,向子類提供了一個共同介面,由子類來完善或者覆蓋它而實現的。8.3 所示。圖中超類Shape規定了兩個實現多態的介面方法,computeArea()以及computeVolume()。子類,如Circle和Sphere為了實現多態,完善或者覆蓋這兩個介面方法。
4.靈活性(flexibility)。它在應用中體現了靈活多樣的操作,提高了使用效率。
5.簡化性(simplicity)。多態簡化對應用軟體的代碼編寫和修改過程,尤其在處理大量對象的運算和操作時,這個特點尤為突出和重要
看到了多態的這麼多好處,是不是覺得很厲害的樣子,就讓我們來看看多態在代碼中的呈現方式(一段神繞的代碼,大家自行觀看,夜深了):
public class StuA { public void say(StuD stu){ System.out.println("D say Hello"); } public void say(StuA stu){ System.out.println("A say Hello"); }}public class StuB extends StuA { public void say(StuA stu){ System.out.println("A say Hello"); } public void say(StuD stu){ System.out.println("B say Hello"); }}public class StuD extends StuA { public void say(StuA stu){ System.out.println("A say Hello"); } public void say(StuB stu){ System.out.println("B say Hello"); }}public static void main(String[] args) { StuA a = new StuA(); StuB b = new StuB(); StuD d = new StuD(); a.say(b); a.say(d); b.say(a); b.say(b); d.say(d); d.say(d); }
在這我也幫不了大家什麼,繞出來多態你就理解的差不多了,運行結果給大家,我要睡覺去了。
A say Hello
D say Hello
A say Hello
A say Hello
D say Hello
D say Hello
黑馬程式員【Java中的物件導向】