【JAVA零基礎入門系列】(已完結)導航目錄html
今天要說的是Java中兩個很是重要的概念——類和對象。前端
什麼是類,什麼又是對象呢?類是對特定集合的歸納描述,好比,人,這個類,外在特徵上,有名字,有年齡,能說話,能吃飯等等,這是咱們做爲人類的相同特徵,那麼對象呢?咱們口口聲聲說要面向對象編程,但是找了這麼久也沒找到對象,這還怎麼編程(滑稽)。此對象非彼對象,Java中的對象是某個具體類的實例,就比如你和我都是人類這個大類的一個實例個體,也就是說,咱們都是人類的一個具體對象,咱們有各自的名字和年齡。java
那爲何要用類和對象這樣的概念呢?算法
這是一個好問題,類是從面向過程編程向面向對象編程轉變的產物。之前的程序,用C語言爲例子,設計程序是算法+數據結構的集合,先設計算法,而後再選擇合適的數據結構去使用算法。而如今面向對象編程則恰好相反,先選擇合適的數據結構,再設計相應的算法來解決問題。簡單來講,面向過程注重考慮的是事情該怎麼作,採用的是上帝視角來處理事情,而面向對象注重的是事情該誰來作,裏面的主角是各鍾類型的對象。面向過程是由上而下的解決問題,而面向對象則是由下而上編程
來舉一個生動形象的栗子,雙十一快到了,該準備剁手了,那具體的剁手步驟呢?數組
面向過程是這樣的:先設置好預算budget,而後選擇商品A,B,C,D,一個個加入收藏,等待雙十一,付款,完成。一步一步有條不紊的進行。各個商品的名稱價格信息分別用兩個字符串數組進行存儲和處理。數據結構
而面向對象則是這樣的:由於須要處理的商品數據,所以能夠構建一個商品類Goods,商品類有名稱,連接,價格等屬性,此外還須要進行商品預算管理,所以能夠構建一個購物車類Cart,對商品進行預算進行統計管理,添加商品,刪除商品等方法,而後再設置一個Money類來對財務進行統一管理,有設置預算,支付等方法,構建好這幾個類以後,須要作的就是新建商品對象,往購物車裏添加商品對象,而後等待雙十一,付款,完成。模塊化
面向對象的思想中,主體是對象,經過對象與對象之間的交互來解決問題,就像上面那樣,關注的是商品等對象,而面向過程則關注的是如何解決問題,即如何在預算範圍內買到合適的商品。函數
固然,你也許會說,這樣一看,彷佛面向對象更加複雜也更加麻煩,對於簡單的問題,確實如此,由於面向對象的出現自己是爲了解決那些複雜的項目,並提供更好的維護方法。因此每每越是複雜的問題,越能體現出面向對象的優越性。那問題來了,既然如此,我舉上面那個栗子來打臉幹嗎呢???切莫着急,等說完後面的內容,最後再來回過頭看看這個問題,就知道怎麼回事了。post
那如今來看看Java中的類究竟是什麼樣的,按慣例先舉個小栗子:
class Goods{ String title; double price; }
這裏定義了一個最簡單的類,由於僅作示例用,它實際上並無什麼卵用,只是爲了說明類的通常定義方式,即class+類名後面再接大括號,在大括號裏面寫上類的屬性及方法。這裏的title跟price都是在類中定義的,也叫作類成員變量,通常在類的最前端定義咱們須要關注的數據變量或者對象,這一部分也稱爲類的實例域。類定義好了,咱們須要使用的話怎麼使用呢?這時候須要用到new關鍵字來建立類的實例,也就是對象。
public class Test{ public static void main(String[] args) { Goods goodsA = new Goods(); goodsA.price=1.1; goodsA.title="123"; System.out.println(goodsA.price); } }
class Goods{
String title;
double price;
}
這裏是在同一個文件下定義和使用類,而實際上,爲了便於管理,一般把每一個類放到單獨的文件中,並用類名來定義文件名,好比Goods類放到Goods.java文件中,而Test則放在Test.java文件中,那一個文件中引用另外一個文件中定義的類,會不會報錯呢?答案是不會的,編譯器會自動幫咱們尋找,只要按規範書寫類名及文件名便可。固然使用IDE的話,在開頭會聲明類所屬的包,關於包的概念在以前已有闡述,這裏就不作過多介紹了。編譯器會自動在包中尋找相應的類。可是須要在Goods的定義前加上public關鍵字,表示能夠被外部類調用。若是須要使用其餘包中的類,則須要使用import關鍵字來導入類,如,import java.util.*;這裏的*表明導入java.util下的全部類,導入以後就能像通常類同樣正常使用了。
如今定義的類,只有屬性,沒有方法,看起來就像是一個將兩個數據捆綁在一個類中而已,就像C語言中的struct。接下來,咱們要擴展這個類。
首先,咱們須要初始化咱們的商品標題和價格,這裏爲了用作介紹,強行使用了初始化塊(滑稽)。
public class Goods{ String title; double price; { title = ""; price = 0.0; } }
初始化塊,顧名思義,就是專門用作初始化的代碼塊,會在類初始化的時候先於構造器運行,由於某些變量的初始化並非賦值這麼簡單,須要通過一些騷操做才能實現,而若是放到構造器中,會顯得臃腫,特別是有多個構造器的時候。因此這裏的初始化塊是大材小用系列。徹底能夠寫成如下形式,這裏只是爲了介紹初始化塊而強行加上的內容。
public class Goods{ String title=」「; double price=0.0; }
接下來加上一個構造器,什麼是構造器?就是構造這個類的一個特殊方法,每一個類都至少有一個構造器。那上面的栗子不是沒有嗎?事實上,若是沒有顯式的添加構造器方法,系統會提供一個默認的無參構造器,可是這個構造器什麼也不作,因此纔會毫無存在感。如今咱們要賦予它神聖的使命,讓它變得有價值起來。
public class Goods{ String title=""; double price=0.0; public Goods(String aTitle,double aPrice){ title = aTitle; price = aPrice; } }
構造器的名稱跟類名一致,前面加上public修飾符,小括號內是參數列表,這裏用了兩個參數,分別用來指定類的title跟price信息。這樣,以前Test類就能夠這樣寫了。
public class Test{ public static void main(String[] args) { Goods goodsA = new Goods("123",1.1); System.out.println(goodsA.price); } }
這樣使用起來是否是更加簡單粗暴,通常的簡單初始化代碼也會放到構造器中進行。咱們還能夠定義多個構造器。
public class Goods{ String title=""; double price=0.0; public Goods(String aTitle,double aPrice){ title = aTitle; price = aPrice; } public Goods(double aPrice){ price = aPrice; title = "Goods"; } }
public class Test{
public static void main(String[] args) {
Goods goodsA = new Goods("notebook",1.1);
Goods goodsB = new Goods(2.2);
System.out.println("goodsA title:"+goodsA.title+" price:"+goodsA.price);
System.out.println("goodsB title:"+goodsB.title+" price:"+goodsB.price);
}
}
這樣既可使用兩個參數的構造器,也可使用只有一個參數的構造器,會執行不一樣的構造器方法。
構造器有了,接下來加上兩個方法,用於讀取價格和標題,以及設置價格和標題。
public class Goods{ private String title=""; private double price=0.0; public Goods(String aTitle,double aPrice){ title = aTitle; price = aPrice; } public Goods(double aPrice){ price = aPrice; title = "Goods"; } public String getTitle(){ return title; } public double getPrice(){ return price; } public void setTitle(String aTitle){ title = aTitle; } public void setPrice(double aPrice){ price = aPrice; } }
這樣咱們的類就已經很豐滿,呸,飽滿了。這裏咱們添加了四個方法,兩個方法用於讀取成員變量,兩個方法用於設置成員變量,此外,咱們還將兩個成員變量設置成了private,這樣這兩個成員變量就只能在類的內部的方法中使用,在其餘類中是禁止使用的。你可能會問,爲何要弄的這樣複雜呢,兩個數據直接操做很差嗎?這就是封裝的意義了,把數據徹底封裝在類裏,只開放接口進行訪問和修改,這樣類就像一個插座同樣,外部代碼不須要知道插座裏面是什麼東西,只須要知道這是三孔插座仍是兩孔插座,知道怎樣使用就能夠了,這樣的好處在於,能夠很方便的進行維護,由於數據形式是容易改變的,但只要提供的接口不改變,其餘代碼就不須要改變,下降代碼之間的依賴程度,這樣就能實現模塊化的效果。
那如今Test類也須要作相應調整了,由於Goods類成員已經聲明爲private了,因此只能經過類方法來進行訪問。一般把用與訪問類成員的方法叫作訪問器,設置類成員的方法叫作更改器。
public class Test{ public static void main(String[] args) { Goods goodsA = new Goods("notebook",1.1); Goods goodsB = new Goods(2.2); System.out.println("goodsA title:"+goodsA.getTitle()+" price:"+goodsA.getPrice()); System.out.println("goodsB title:"+goodsB.getTitle()+" price:"+goodsB.getPrice()); } }
好了,如今咱們的類變得有些厲害了,那若是如今須要將商品連接也加進去,該怎麼辦呢?
public class Goods{ private String title=""; private double price=0.0; private String link = ""; public Goods(String aTitle,double aPrice,String aLink){ title = aTitle; price = aPrice; link = aLink; } public Goods(String aTitle,double aPrice){ title = aTitle; price = aPrice; link = "www.baidu.com"; } public Goods(double aPrice){ price = aPrice; title = "Goods"; link = "www.baidu.com"; } public String getTitle(){ return title; } public double getPrice(){ return price; } public String getLink() { return link; } public void setTitle(String aTitle){ title = aTitle; } public void setPrice(double aPrice){ price = aPrice; } public void setLink(String aLink){ link = aLink; } }
加上一個成員變量,再加上相應的訪問器和更改器便可,固然,這裏新增了一個構造器,這樣的話,不只以前的代碼仍可使用,還能使用新方法,騷出新高度。
public class Test{ public static void main(String[] args) { Goods goodsA = new Goods("notebook",1.1); Goods goodsB = new Goods(2.2); Goods goodsC = new Goods("Java class",233,"www.cnblogs.com/mfrank/p/7747587.html"); System.out.println("goodsA title:"+goodsA.getTitle()+" price:"+goodsA.getPrice()+" link:"+goodsA.getLink()); System.out.println("goodsB title:"+goodsB.getTitle()+" price:"+goodsB.getPrice()+" link:"+goodsB.getLink()); System.out.println("goodsC title:"+goodsC.getTitle()+" price:"+goodsC.getPrice()+" link:"+goodsC.getLink()); } }
這樣就能輸出三個對象的全部信息了,等等,不以爲輸出的時候太麻煩了嗎,重複三次及以上的地方就須要考慮用一個函數來代替。嗯,來給咱們的Goods類加上一個輸出方法。
public class Goods{ private String title=""; private double price=0.0; private String link = ""; public Goods(String aTitle,double aPrice,String aLink){ title = aTitle; price = aPrice; link = aLink; } public Goods(String aTitle,double aPrice){ title = aTitle; price = aPrice; link = "www.baidu.com"; } public Goods(double aPrice){ price = aPrice; title = "Goods"; link = "www.baidu.com"; } public String getTitle(){ return title; } public double getPrice(){ return price; } public String getLink() { return link; } public void setTitle(String aTitle){ title = aTitle; } public void setPrice(double aPrice){ price = aPrice; } public void setLink(String aLink){ link = aLink; } public void print(){ System.out.println("title:"+title+" price:"+price+" link:"+link); } }
public class Test{ public static void main(String[] args) { Goods goodsA = new Goods("notebook",1.1); Goods goodsB = new Goods(2.2); Goods goodsC = new Goods("Java class",233,"www.cnblogs.com/mfrank/p/7747587.html"); goodsA.print(); goodsB.print(); goodsC.print(); } }
你看,咱們的類定義好以後,主函數裏的代碼是否是就變得很簡單了。這就是封裝的好處,封裝好之後只須要知道怎樣使用就好了,不須要關注內部是怎樣實現的。
好了,關於類與對象的內容就說到這了,總結一下,類是某一特定集合的特徵描述,對象是類的具體實例,在使用的時候類的時候,須要用new關鍵字來new一個對象,而後才能使用類方法來操做這個對象。類能夠看做是對象的模版,就像一個工廠同樣,能夠生成衣服,但每件衣服的款式是能夠不同的。
至此,本篇講解結束,歡迎你們繼續關注。