重新認(rèn)識java(二) ---- 面向?qū)ο笾庋b!

如果你認(rèn)為封裝僅僅是private + getter and setter乐纸,那你就大錯(cuò)特錯(cuò)了衬廷!

什么是封裝

對于面向?qū)ο蟮奶攸c(diǎn),我想大家都可以倒背如流了:封裝汽绢,繼承吗跋,多態(tài)。很多人對這些特點(diǎn)的理解僅僅停留在表面宁昭。以為封裝就是變量私有化跌宛,然后對外提供接口,而不知為什么要這樣做积仗。

封裝疆拘,簡單的來講就是將變量的屬性私有化,在java里就是用private修飾符修飾寂曹,這樣在外部產(chǎn)生的對象就不能直接訪問到這個(gè)變量哎迄。想要對變量進(jìn)行操作或者訪問回右,就需要在類里提供外部訪問的接口,也就是我們熟知的get和set方法漱挚。

這就是大部分人對封裝的理解翔烁。知道有封裝這回事,知道怎么用棱烂,卻不知道為什么要用租漂,甚至覺得這是多此一舉阶女。因?yàn)槊髅?code>person.name就可以訪問到變量颊糜,為什么非要person.getName()呢?

任性的使用public

我們先來看一下不使用封裝的情況秃踩。

首先衬鱼,有兩個(gè)類,Man和Women:

//Man
public class Man {
    public String name; //名字
    public Woman wife;  //男人嘛憔杨,都有妻子
    public double money;//男人嘛鸟赫,多賺點(diǎn)錢

    //還可以結(jié)個(gè)婚
    public void marry(Woman woman){
        this.wife = woman;
        woman.marry(this);
    }
}
//Women
public class Woman {
    public String name; //名字
    public Man husband; //得有一個(gè)丈夫
    //也可以結(jié)個(gè)婚
    public void marry(Man man){
        this.husband = man;
    }
}

代碼很精簡,看著很舒服消别,測試一下抛蚤。

哎喲,看起來還不錯(cuò)寻狂。

這個(gè)時(shí)候岁经,來了一個(gè)小偷,這小偷不干別的蛇券,就偷別人的錢和老婆缀壤。

//小偷
public class Thief {
    private double stealMoney = 0;
    private List<Woman> womens = new ArrayList<>();

    //偷錢
    public void stealMoney(Man man){
        stealMoney += man.money;
        man.money = 0;
        System.out.println("哈哈,偷到錢了");
    }
    //偷老婆纠亚,最可氣的是塘慕,偷了你的老婆還把鳳姐丟給了你
    public void stealWife(Man man){
        womens.add(man.wife);
        Woman woman = new Woman();
        woman.name = "鳳姐";
        man.wife = woman;
        System.out.println("哈哈哈,又偷了一個(gè)妹紙");
    }
}

有一天蒂胞,來了這么一個(gè)小偷:

傻了吧图呢?你老婆呢?你錢呢骗随?哈哈哈哈哈哈哈哈哈

就這樣岳瞭,小偷偷走了你的錢和你的老婆并丟給了你一個(gè)鳳姐,而你蚊锹,卻無能為力瞳筏。

你覺得必須要改變一下了!牡昆!

封裝前來報(bào)到

封裝覺得你有點(diǎn)慘姚炕,于是過來幫了一下你:

//PackageMan
public class PackageMan {
    private String name; //私有化名字
    private PackageWoman wife;//必須私有L贰!必須柱宦!
    private double money; //私有些椒,統(tǒng)統(tǒng)私有!
    //我們先寫個(gè)構(gòu)造函數(shù)掸刊,為了方便
    public PackageMan(String name, double money) {
        this.name = name;
        this.money = money;
    }
    //結(jié)婚
    public void marry(PackageWoman woman){
        this.wife = woman;
        woman.marry(this);
    }

    //各種getter和setter
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public PackageWoman getWife() {
        return wife;
    }

    public double getMoney() {
        return money;
    }
}

//PackageWoman
public class PackageWoman {
    private String name;
    private PackageMan husband;

    public void marry(PackageMan man){
        this.husband = man;
    }

    public PackageWoman(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public PackageMan getHusband() {
        return husband;
    }

    public void setName(String name) {
        this.name = name;
    }
}

看起來有點(diǎn)眼花繚亂免糕,這樣真的有效么?

恩忧侧,看起來還行石窑,就是代碼長了點(diǎn),趕緊給我來個(gè)小偷測試一下蚓炬!

什么松逊?你想測試一下,不好意思肯夏,測試不了经宏,因?yàn)樾⊥狄呀?jīng)死在測試的路上了。因?yàn)槲覀兏緵]有對外提供設(shè)置money和wife的方法驯击,所以小偷可以知道你有多少錢烁兰,知道你有一個(gè)漂亮的老婆,但是他卻無能為力徊都,因?yàn)樗荒芸粗?/p>

細(xì)心的人也許發(fā)現(xiàn)了沪斟,這里面有一個(gè)很嚴(yán)重的問題:

沒錯(cuò),小偷不能把我們的money清空了碟贾,也不能將我們的wife換成別人了币喧。但是,如果我們要自己換呢袱耽?我的錢這輩子就這么點(diǎn)杀餐?還不能花?我還不能離婚了朱巨?(咳咳史翘。。不鼓勵離婚哈冀续,就是舉個(gè)例子琼讽,別打我)

這才是封裝厲害的地方

如何解決上面的問題呢?私有化外部訪問不到洪唐,自己也沒法改變數(shù)據(jù)钻蹬,提供set方法又會讓所有人都能改,和不私有沒什么區(qū)別凭需,好糾結(jié)啊问欠。

等等肝匆,你剛剛說 “所有人“?真的是所有人么顺献?

我們來看看:

public void setMoney(PackageMan man,double money) {
    if (man == this) {
        this.money = money;
    } else {
        System.out.println("喂旗国,110嗎?"+man.getName()+"搶錢注整!");
    }
}

這樣呢能曾?只有你自己可以修改,別人都不可以肿轨,測試一下:

這樣就可以了寿冕,自己可以修改,但是別人不可以萝招。

但是你老婆不滿意了蚂斤,憑什么只有你自己能改存捺?我也想改槐沼!

這種要求,還是應(yīng)該滿足一下的捌治,怎么做呢岗钩?

public void setMoney(Object o,double money) {
    if (o == this || o == this.wife) {
        this.money = money;
    } else {
        System.out.println("喂,110嗎肖油?有人搶錢兼吓!");
    }
}

這樣就可以了。

當(dāng)然森枪,愛思考的人肯定發(fā)現(xiàn)了视搏,我把搶錢的那句話修改了,沒有獲取修改人的名字县袱,因?yàn)閭魅氲氖荗bjects對象浑娜。當(dāng)然,你也可以再寫點(diǎn)代碼式散,判斷一下傳進(jìn)來的是什么筋遭,然后搶轉(zhuǎn)為相應(yīng)的類型,再調(diào)用相應(yīng)的方法暴拄。

除此之外漓滔,就沒有別的辦法了么?當(dāng)然有乖篷,具體怎么做响驴,我們下一篇文章再做分解。下一篇文章《重新認(rèn)識java(三) ---- 面向?qū)ο笾^承》不定期更新撕蔼。

仔細(xì)思考一下你會發(fā)現(xiàn)豁鲤,我特么竟然是在騙你石蔗!因?yàn)楫?dāng)你提供了set函數(shù)以后,小偷又可以偷你的東西了畅形。仔細(xì)看一下之前小偷是怎么偷你東西的你就知道了养距。

沒錯(cuò),就是通過你自己日熬。小偷通過你自己改變了你自己棍厌。聽起來有點(diǎn)扯,但是事實(shí)上就是這樣的竖席。

那么耘纱,有沒有一種辦法讓小偷在只得到”你自己“的情況下怎么樣都不能改變“你的屬性值”,而只有你自己能改變呢毕荐?

大家可以自己想想束析,具體的解決辦法,我們在之后的文章里揭曉憎亚。敬請期待员寇。

總結(jié)一下

以上就是面向?qū)ο蟮姆庋b,封裝不僅僅只是private + getter and setter第美。使用封裝可以對setter進(jìn)行更深層次的定制蝶锋。你可以對可以執(zhí)行setter方法的對象做規(guī)定,也可以對數(shù)據(jù)作要求什往,還可以做類型轉(zhuǎn)換等等一系列你可以想到的扳缕。

使用封裝不僅僅是安全,更可以簡化操作别威。不要覺得用了封裝多了好多代碼躯舔,看起來亂糟糟的。這只是因?yàn)槲遗e得例子太小了省古。如果你寫你個(gè)大的系統(tǒng)粥庄,一開始你的這樣定義類的

public int age;

你的程序里大概有100處這樣的語句:

p.age = 10;

這個(gè)時(shí)候,突然要求你把數(shù)據(jù)類型變了衫樊,改成:

public String age;

你是不是要把那100處數(shù)據(jù)都加個(gè)雙引號呢飒赃?這是不是很麻煩?

如果你用了封裝科侈,你只需要這樣:

public void setAge(int age){
    this.age = String.valueOf(age);
}

然后就搞定了载佳,是不是簡化了操作?

我只是舉個(gè)例子臀栈,實(shí)際開發(fā)中也不會出現(xiàn)改變數(shù)據(jù)類型這么操蛋的事蔫慧。。

封裝還有一個(gè)好處是模塊化权薯。當(dāng)你參與一個(gè)很多人實(shí)現(xiàn)的大型系統(tǒng)中姑躲,你不可能知道所有的類是怎樣實(shí)現(xiàn)的睡扬。你只需要知道這個(gè)類給我提供了哪些方法,我需要傳入什么數(shù)據(jù)黍析,我能得到什么結(jié)果卖怜。至于怎么得到的,關(guān)我x事阐枣?

所以說马靠,如果你寫的代碼還沒有用封裝,改過來吧蔼两。不是因?yàn)榇蠹叶加盟阅阋矐?yīng)該用甩鳄,而是這確實(shí)可以給你提供極大的便利。

結(jié)束~


有什么疑問或者錯(cuò)誤可以給我留言

下篇文章見~

轉(zhuǎn)載請注明出處6罨C羁小!?〈痢揖赴!
本文原創(chuàng)自csdn和簡書!品抽!
csdn地址:http://m.blog.csdn.net/article/details?id=53381737
簡書地址:http://www.reibang.com/p/9cc3a832fabb

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末储笑,一起剝皮案震驚了整個(gè)濱河市甜熔,隨后出現(xiàn)的幾起案子圆恤,更是在濱河造成了極大的恐慌,老刑警劉巖腔稀,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盆昙,死亡現(xiàn)場離奇詭異,居然都是意外死亡焊虏,警方通過查閱死者的電腦和手機(jī)淡喜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诵闭,“玉大人炼团,你說我怎么就攤上這事∈枘颍” “怎么了瘟芝?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長褥琐。 經(jīng)常有香客問我锌俱,道長,這世上最難降的妖魔是什么敌呈? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任贸宏,我火速辦了婚禮造寝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吭练。我一直安慰自己诫龙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布鲫咽。 她就那樣靜靜地躺著赐稽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浑侥。 梳的紋絲不亂的頭發(fā)上姊舵,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音寓落,去河邊找鬼括丁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伶选,可吹牛的內(nèi)容都是我干的史飞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼仰税,長吁一口氣:“原來是場噩夢啊……” “哼构资!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起陨簇,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤吐绵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后河绽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體己单,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年耙饰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纹笼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡苟跪,死狀恐怖廷痘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情件已,我是刑警寧澤笋额,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站拨齐,受9級特大地震影響鳞陨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一厦滤、第九天 我趴在偏房一處隱蔽的房頂上張望援岩。 院中可真熱鬧,春花似錦掏导、人聲如沸享怀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽添瓷。三九已至,卻和暖如春值纱,著一層夾襖步出監(jiān)牢的瞬間鳞贷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工虐唠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搀愧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓疆偿,卻偏偏與公主長得像咱筛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子杆故,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

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