【JAVA 零基礎(chǔ)入門系列】Day11 Java 中的類和對象

??今天要說的是 Java 中兩個非常重要的概念——類和對象颤诀。

??什么是類,什么又是對象呢对湃?類是對特定集合的概括描述崖叫,比如,人拍柒,這個類心傀,外在特征上,有名字拆讯,有年齡脂男,能說話,能吃飯等等种呐,這是我們作為人類的相同特征宰翅,那么對象呢?我們口口聲聲說要面向?qū)ο缶幊趟遥墒钦伊诉@么久也沒找到對象汁讼,這還怎么編程(滑稽)。此對象非彼對象阔墩,Java 中的對象是某個具體類的實例嘿架,就好比你和我都是人類這個大類的一個實例個體,也就是說啸箫,我們都是人類的一個具體對象耸彪,我們有各自的名字和年齡。

??那為什么要用類和對象這樣的概念呢忘苛?

??這是一個好問題搜囱,類是從面向過程編程向面向?qū)ο缶幊剔D(zhuǎn)變的產(chǎn)物丑瞧。以前的程序,用 C 語言為例子蜀肘,設(shè)計程序是算法 + 數(shù)據(jù)結(jié)構(gòu)的集合绊汹,先設(shè)計算法,然后再選擇合適的數(shù)據(jù)結(jié)構(gòu)去使用算法扮宠。而現(xiàn)在面向?qū)ο缶幊虅t剛好相反西乖,先選擇合適的數(shù)據(jù)結(jié)構(gòu),再設(shè)計相應(yīng)的算法來解決問題坛增。簡單來說获雕,面向過程注重考慮的是事情該怎么做,采用的是上帝視角來處理事情收捣,而面向?qū)ο笞⒅氐氖鞘虑樵撜l來做届案,里面的主角是各鐘類型的對象。面向過程是由上而下的解決問題罢艾,而面向?qū)ο髣t是由下而上

??來舉一個生動形象的栗子楣颠,雙十一快到了,該準備剁手了咐蚯,那具體的剁手步驟呢童漩?

??面向過程是這樣的:先設(shè)置好預(yù)算 budget,然后選擇商品 A,B,C,D春锋,一個個加入收藏矫膨,等待雙十一,付款期奔,完成侧馅。一步一步有條不紊的進行。各個商品的名稱價格信息分別用兩個字符串?dāng)?shù)組進行存儲和處理呐萌。

??而面向?qū)ο髣t是這樣的:因為需要處理的商品數(shù)據(jù)施禾,因此可以構(gòu)建一個商品類 Goods,商品類有名稱搁胆,鏈接弥搞,價格等屬性,此外還需要進行商品預(yù)算管理渠旁,因此可以構(gòu)建一個購物車類 Cart攀例,對商品進行預(yù)算進行統(tǒng)計管理,添加商品顾腊,刪除商品等方法粤铭,然后再設(shè)置一個 Money 類來對財務(wù)進行統(tǒng)一管理,有設(shè)置預(yù)算杂靶,支付等方法梆惯,構(gòu)建好這幾個類之后酱鸭,需要做的就是新建商品對象,往購物車里添加商品對象垛吗,然后等待雙十一凹髓,付款,完成怯屉。

??面向?qū)ο蟮乃枷胫形狄ǎ黧w是對象,通過對象與對象之間的交互來解決問題锨络,就像上面那樣赌躺,關(guān)注的是商品等對象,而面向過程則關(guān)注的是如何解決問題羡儿,即如何在預(yù)算范圍內(nèi)買到合適的商品礼患。

??當(dāng)然,你也許會說掠归,這樣一看缅叠,似乎面向?qū)ο蟾訌?fù)雜也更加麻煩,對于簡單的問題拂到,確實如此,因為面向?qū)ο蟮某霈F(xiàn)本身是為了解決那些復(fù)雜的項目码泞,并提供更好的維護方法兄旬。所以往往越是復(fù)雜的問題,越能體現(xiàn)出面向?qū)ο蟮膬?yōu)越性余寥。那問題來了领铐,既然如此,我舉上面那個栗子來打臉干嘛呢宋舷?绪撵??切莫著急祝蝠,等說完后面的內(nèi)容音诈,最后再來回過頭看看這個問題,就知道怎么回事了绎狭。

??那現(xiàn)在來看看 Java 中的類到底是什么樣的细溅,按慣例先舉個小栗子:

class Goods{
  String title;
  double price;
}

??這里定義了一個最簡單的類,因為僅做示例用儡嘶,它實際上并沒有什么卵用喇聊,只是為了說明類的一般定義方式,即 class + 類名后面再接大括號蹦狂,在大括號里面寫上類的屬性及方法誓篱。這里的 title 跟 price 都是在類中定義的朋贬,也叫做類成員變量,一般在類的最前端定義我們需要關(guān)注的數(shù)據(jù)變量或者對象窜骄,這一部分也稱為類的實例域锦募。類定義好了,我們需要使用的話怎么使用呢啊研?這時候需要用到 new 關(guān)鍵字來創(chuàng)建類的實例御滩,也就是對象。

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 文件中济似,那一個文件中引用另一個文件中定義的類撬统,會不會報錯呢?答案是不會的纳猫,編譯器會自動幫我們尋找虱岂,只要按規(guī)范書寫類名及文件名即可。當(dāng)然使用 IDE 的話台舱,在開頭會聲明類所屬的包律杠,關(guān)于包的概念在之前已有闡述,這里就不做過多介紹了竞惋。編譯器會自動在包中尋找相應(yīng)的類柜去。但是需要在 Goods 的定義前加上 public 關(guān)鍵字,表示可以被外部類調(diào)用拆宛。如果需要使用其他包中的類嗓奢,則需要使用 import 關(guān)鍵字來導(dǎo)入類,如浑厚,import java.util.*股耽;這里的 * 代表導(dǎo)入 java.util 下的所有類,導(dǎo)入之后就能像一般類一樣正常使用了钳幅。

image
image
image

??現(xiàn)在定義的類豺谈,只有屬性,沒有方法贡这,看起來就像是一個將兩個數(shù)據(jù)捆綁在一個類中而已茬末,就像 C 語言中的 struct。接下來,我們要擴展這個類丽惭。

??首先击奶,我們需要初始化我們的商品標題和價格,這里為了用做介紹责掏,強行使用了初始化塊(滑稽)柜砾。

public class Goods{
    String title;
    double price;
    {
        title = "";
        price = 0.0;
    }
}

??初始化塊,顧名思義换衬,就是專門用做初始化的代碼塊痰驱,會在類初始化的時候先于構(gòu)造器運行,因為某些變量的初始化并不是賦值這么簡單瞳浦,需要經(jīng)過一些騷操作才能實現(xiàn)担映,而如果放到構(gòu)造器中,會顯得臃腫叫潦,特別是有多個構(gòu)造器的時候蝇完。所以這里的初始化塊是大材小用系列。完全可以寫成以下形式矗蕊,這里只是為了介紹初始化塊而強行加上的內(nèi)容短蜕。

public class Goods{
    String title=”“;
    double price=0.0;
}

??接下來加上一個構(gòu)造器,什么是構(gòu)造器傻咖?就是構(gòu)造這個類的一個特殊方法朋魔,每個類都至少有一個構(gòu)造器。那上面的栗子不是沒有嗎卿操?事實上警检,如果沒有顯式的添加構(gòu)造器方法,系統(tǒng)會提供一個默認的無參構(gòu)造器硬纤,但是這個構(gòu)造器什么也不做解滓,所以才會毫無存在感≡吣ィ現(xiàn)在我們要賦予它神圣的使命筝家,讓它變得有價值起來。

public class Goods{
    String title="";
    double price=0.0;
    public Goods(String aTitle,double aPrice){
        title = aTitle;
        price = aPrice;
    }
}

??構(gòu)造器的名稱跟類名一致邻辉,前面加上 public 修飾符溪王,小括號內(nèi)是參數(shù)列表,這里用了兩個參數(shù)值骇,分別用來指定類的 title 跟 price 信息莹菱。這樣,之前 Test 類就可以這樣寫了吱瘩。

public class Test{
    public static void main(String[] args) {
        Goods goodsA = new Goods("123",1.1);
        System.out.println(goodsA.price);
    }
}

??這樣使用起來是不是更加簡單粗暴道伟,一般的簡單初始化代碼也會放到構(gòu)造器中進行。我們還可以定義多個構(gòu)造器。

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);
    }
}

??這樣既可以使用兩個參數(shù)的構(gòu)造器蜜徽,也可以使用只有一個參數(shù)的構(gòu)造器祝懂,會執(zhí)行不同的構(gòu)造器方法。

??構(gòu)造器有了拘鞋,接下來加上兩個方法砚蓬,用于讀取價格和標題,以及設(shè)置價格和標題盆色。

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;
    }
}

??這樣我們的類就已經(jīng)很豐滿灰蛙,呸,飽滿了隔躲。這里我們添加了四個方法摩梧,兩個方法用于讀取成員變量,兩個方法用于設(shè)置成員變量蹭越,此外障本,我們還將兩個成員變量設(shè)置成了 private,這樣這兩個成員變量就只能在類的內(nèi)部的方法中使用响鹃,在其他類中是禁止使用的驾霜。你可能會問,為什么要弄的這樣復(fù)雜呢买置,兩個數(shù)據(jù)直接操作不好嗎粪糙?這就是封裝的意義了,把數(shù)據(jù)完全封裝在類里忿项,只開放接口進行訪問和修改蓉冈,這樣類就像一個插座一樣,外部代碼不需要知道插座里面是什么東西轩触,只需要知道這是三孔插座還是兩孔插座寞酿,知道怎樣使用就可以了,這樣的好處在于脱柱,可以很方便的進行維護伐弹,因為數(shù)據(jù)形式是容易改變的,但只要提供的接口不改變榨为,其他代碼就不需要改變惨好,降低代碼之間的依賴程度,這樣就能實現(xiàn)模塊化的效果随闺。

??那現(xiàn)在 Test 類也需要做相應(yīng)調(diào)整了日川,因為 Goods 類成員已經(jīng)聲明為 private 了,所以只能通過類方法來進行訪問矩乐。通常把用與訪問類成員的方法叫做訪問器龄句,設(shè)置類成員的方法叫做更改器。

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());
    }
}

??好了,現(xiàn)在我們的類變得有些厲害了分歇,那如果現(xiàn)在需要將商品鏈接也加進去透葛,該怎么辦呢?

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;
    }
}

??加上一個成員變量卿樱,再加上相應(yīng)的訪問器和更改器即可僚害,當(dāng)然,這里新增了一個構(gòu)造器繁调,這樣的話萨蚕,不僅之前的代碼仍可以使用,還能使用新方法蹄胰,騷出新高度岳遥。

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());
    }
}

??這樣就能輸出三個對象的所有信息了,等等裕寨,不覺得輸出的時候太麻煩了嗎浩蓉,重復(fù)三次及以上的地方就需要考慮用一個函數(shù)來代替。嗯宾袜,來給我們的 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();
    }
}

??你看,我們的類定義好之后庆猫,主函數(shù)里的代碼是不是就變得很簡單了认轨。這就是封裝的好處,封裝好以后只需要知道怎樣使用就行了月培,不需要關(guān)注內(nèi)部是怎樣實現(xiàn)的嘁字。

??好了,關(guān)于類與對象的內(nèi)容就說到這了杉畜,總結(jié)一下纪蜒,類是某一特定集合的特征描述,對象是類的具體實例此叠,在使用的時候類的時候纯续,需要用 new 關(guān)鍵字來 new 一個對象,然后才能使用類方法來操作這個對象拌蜘。類可以看作是對象的模版杆烁,就像一個工廠一樣牙丽,可以生成衣服简卧,但每件衣服的款式是可以不一樣的。

??至此烤芦,本篇講解結(jié)束举娩,歡迎大家繼續(xù)關(guān)注。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市铜涉,隨后出現(xiàn)的幾起案子智玻,更是在濱河造成了極大的恐慌,老刑警劉巖芙代,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吊奢,死亡現(xiàn)場離奇詭異,居然都是意外死亡纹烹,警方通過查閱死者的電腦和手機页滚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铺呵,“玉大人裹驰,你說我怎么就攤上這事∑遥” “怎么了幻林?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長音念。 經(jīng)常有香客問我沪饺,道長,這世上最難降的妖魔是什么闷愤? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任随闽,我火速辦了婚禮,結(jié)果婚禮上肝谭,老公的妹妹穿的比我還像新娘掘宪。我一直安慰自己,他們只是感情好攘烛,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布魏滚。 她就那樣靜靜地躺著,像睡著了一般坟漱。 火紅的嫁衣襯著肌膚如雪鼠次。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天芋齿,我揣著相機與錄音腥寇,去河邊找鬼。 笑死觅捆,一個胖子當(dāng)著我的面吹牛赦役,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播栅炒,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼掂摔,長吁一口氣:“原來是場噩夢啊……” “哼术羔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起乙漓,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤级历,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后叭披,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寥殖,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年涩蜘,在試婚紗的時候發(fā)現(xiàn)自己被綠了扛禽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡皱坛,死狀恐怖编曼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情剩辟,我是刑警寧澤掐场,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站贩猎,受9級特大地震影響熊户,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吭服,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一嚷堡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧艇棕,春花似錦蝌戒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至打瘪,卻和暖如春友鼻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闺骚。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工彩扔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人僻爽。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓虫碉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親进泼。 傳聞我的和親對象是個殘疾皇子蔗衡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容