重新认识java(二) ---- 面向对象之封装!

如果你认为封装仅仅是private + getter and setter,那你就大错特错了!

什么是封装

对于面向对象的特点,我想大家都可以倒背如流了:封装,继承,多态。很多人对这些特点的理解仅仅停留在表面。以为封装就是变量私有化,然后对外提供接口,而不知为什么要这样做。

封装,简单的来讲就是将变量的属性私有化,在java里就是用private修饰符修饰,这样在外部产生的对象就不能直接访问到这个变量。想要对变量进行操作或者访问,就需要在类里提供外部访问的接口,也就是我们熟知的get和set方法。

这就是大部分人对封装的理解。知道有封装这回事,知道怎么用,却不知道为什么要用,甚至觉得这是多此一举。因为明明person.name就可以访问到变量,为什么非要person.getName()呢?

任性的使用public

我们先来看一下不使用封装的情况。

首先,有两个类,Man和Women:

//Man
public class Man {
    public String name; //名字
    public Woman wife;  //男人嘛,都有妻子
    public double money;//男人嘛,多赚点钱

    //还可以结个婚
    public void marry(Woman woman){
        this.wife = woman;
        woman.marry(this);
    }
}
//Women
public class Woman {
    public String name; //名字
    public Man husband; //得有一个丈夫
    //也可以结个婚
    public void marry(Man man){
        this.husband = man;
    }
}

代码很精简,看着很舒服,测试一下。

哎哟,看起来还不错。

这个时候,来了一个小偷,这小偷不干别的,就偷别人的钱和老婆。

//小偷
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("哈哈哈,又偷了一个妹纸");
    }
}

有一天,来了这么一个小偷:

傻了吧?你老婆呢?你钱呢?哈哈哈哈哈哈哈哈哈

就这样,小偷偷走了你的钱和你的老婆并丢给了你一个凤姐,而你,却无能为力。

你觉得必须要改变一下了!!

封装前来报到

封装觉得你有点惨,于是过来帮了一下你:

//PackageMan
public class PackageMan {
    private String name; //私有化名字
    private PackageWoman wife;//必须私有!!必须!
    private double money; //私有,统统私有!
    //我们先写个构造函数,为了方便
    public PackageMan(String name, double money) {
        this.name = name;
        this.money = money;
    }
    //结婚
    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;
    }
}

看起来有点眼花缭乱,这样真的有效么?

恩,看起来还行,就是代码长了点,赶紧给我来个小偷测试一下!

什么?你想测试一下,不好意思,测试不了,因为小偷已经死在测试的路上了。因为我们根本没有对外提供设置money和wife的方法,所以小偷可以知道你有多少钱,知道你有一个漂亮的老婆,但是他却无能为力,因为他只能看着。

细心的人也许发现了,这里面有一个很严重的问题:

没错,小偷不能把我们的money清空了,也不能将我们的wife换成别人了。但是,如果我们要自己换呢?我的钱这辈子就这么点?还不能花?我还不能离婚了?(咳咳。。不鼓励离婚哈,就是举个例子,别打我)

这才是封装厉害的地方

如何解决上面的问题呢?私有化外部访问不到,自己也没法改变数据,提供set方法又会让所有人都能改,和不私有没什么区别,好纠结啊。

等等,你刚刚说 “所有人“?真的是所有人么?

我们来看看:

public void setMoney(PackageMan man,double money) {
    if (man == this) {
        this.money = money;
    } else {
        System.out.println("喂,110吗?"+man.getName()+"抢钱!");
    }
}

这样呢?只有你自己可以修改,别人都不可以,测试一下:

这样就可以了,自己可以修改,但是别人不可以。

但是你老婆不满意了,凭什么只有你自己能改?我也想改!

这种要求,还是应该满足一下的,怎么做呢?

public void setMoney(Object o,double money) {
    if (o == this || o == this.wife) {
        this.money = money;
    } else {
        System.out.println("喂,110吗?有人抢钱!");
    }
}

这样就可以了。

当然,爱思考的人肯定发现了,我把抢钱的那句话修改了,没有获取修改人的名字,因为传入的是Objects对象。当然,你也可以再写点代码,判断一下传进来的是什么,然后抢转为相应的类型,再调用相应的方法。

除此之外,就没有别的办法了么?当然有,具体怎么做,我们下一篇文章再做分解。下一篇文章《重新认识java(三) ---- 面向对象之继承》不定期更新。

仔细思考一下你会发现,我特么竟然是在骗你!因为当你提供了set函数以后,小偷又可以偷你的东西了。仔细看一下之前小偷是怎么偷你东西的你就知道了。

没错,就是通过你自己。小偷通过你自己改变了你自己。听起来有点扯,但是事实上就是这样的。

那么,有没有一种办法让小偷在只得到”你自己“的情况下怎么样都不能改变“你的属性值”,而只有你自己能改变呢?

大家可以自己想想,具体的解决办法,我们在之后的文章里揭晓。敬请期待。

总结一下

以上就是面向对象的封装,封装不仅仅只是private + getter and setter。使用封装可以对setter进行更深层次的定制。你可以对可以执行setter方法的对象做规定,也可以对数据作要求,还可以做类型转换等等一系列你可以想到的。

使用封装不仅仅是安全,更可以简化操作。不要觉得用了封装多了好多代码,看起来乱糟糟的。这只是因为我举得例子太小了。如果你写你个大的系统,一开始你的这样定义类的

public int age;

你的程序里大概有100处这样的语句:

p.age = 10;

这个时候,突然要求你把数据类型变了,改成:

public String age;

你是不是要把那100处数据都加个双引号呢?这是不是很麻烦?

如果你用了封装,你只需要这样:

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

然后就搞定了,是不是简化了操作?

我只是举个例子,实际开发中也不会出现改变数据类型这么操蛋的事。。

封装还有一个好处是模块化。当你参与一个很多人实现的大型系统中,你不可能知道所有的类是怎样实现的。你只需要知道这个类给我提供了哪些方法,我需要传入什么数据,我能得到什么结果。至于怎么得到的,关我x事?

所以说,如果你写的代码还没有用封装,改过来吧。不是因为大家都用所以你也应该用,而是这确实可以给你提供极大的便利。

结束~


有什么疑问或者错误可以给我留言

下篇文章见~

转载请注明出处!!!!!
本文原创自csdn和简书!!
csdn地址:http://m.blog.csdn.net/article/details?id=53381737
简书地址:http://www.jianshu.com/p/9cc3a832fabb

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容