又见手把手系列-面向对象扫盲-通俗的OO第一弹-【封装】
2007-09-21 16:19
309 查看
最近针对OO有了太多的讨论,太多的误会,太多的不理解。让我来一次性解决什么是对象,为什么要面向对象的问题吧,这是第一篇。
所谓面向对象的编程、设计、思想。我们用大白话来说。
面向对象就是用 某物(对象),是什么(类),有什么(对象的状态),能干什么(方法)的方式来描述程序的方法。这就是面向对象。
面向对象的程序的特征,封装性:也就是某物状态的改变,必须是他自己的行为来改变。
打个比方,我(人类),有钱(有什么),你(人类),要找我借钱(能干什么)。于是
class Man()
{
private int money;
public int Money
{
get{return money}
set{money=value}
}
public void Borrow(Man Target,int Howmuch)
{
money+=Howmuch;
Target.Money-=Howmuch;
}
}
就是这个样子。这样子的写法是不对的,这样破坏类的封装性,我们绕过了Man的对象,直接去操作了对象的状态。这完全是强盗逻辑,跟你直接到我钱包里掏钱一样不可饶恕。所以,借钱这个动作还需要我来参与,你找我借钱,而我,要借给你钱。我们修改一下类的代码。我们给Man类增加一个Lend的方法,以封装在借出钱的时候对自身状态的改变。然后借钱的行为也要更改了。
class Man()
{
private int money;
public int Money
{
get{return money}
set{money=value}
}
public bool Lend(int Howmuch)
{
if(Howmuch<money)
{
money-=Howmuch;
return true;
}else
{
return false;
}
}
public void Borrow(Man Target,int Howmuch)
{
money+=Howmuch;
Target.Lend(Howmuch);
}
}
这样子的代码就是满足了封装性的原则,注意,封装既是特征,也是必须满足的条件,如果破坏了封装性原则那就是破坏了OO的原则。
这里回到了一个很实际的问题,失血模型为什么不OO。
我们定义了Book类,封装了Book的状态(属性)。如果我们用一个BookManager类去Save这本书(典型的失学模式的做法)。那么,我们在BookManager中如何保存?很多人在BookManager.Save里读取Book的属性,生成SQL,写数据库,返回执行结果。这样子OO么?不OO,因为这种做法完全破坏了封装性的原则。就跟之前借钱的例子一样。所以我们要在Book类增加一个Save方法,这个方法是用来维护Book类本身的状态的。而很多的ORM也能够给我们的类注入这类方法,使我们的的类具备持久化的能力。这样Book的属性,如何在数据库里存储,如何读取,如何删除都是Book自身来负责,因为在数据库里关于Book 的记录都是属于Book的状态,所以都需要Book自身来封装,使其透明化。
很多人在之前我写的Book.Save是否OO的话题里面说,觉得Book.Save方法仅仅是换了个位置。但是哪里知道,这个小小的改变却是一个原则性的问题。而至于双鱼座觉得在Save里加入上下文的参数更加符合实际情况,我个人觉的加和不加对Book类是否符合OO的原则没有太大的影响。
但是有和没有确是天壤之别了。
封装是保证系统的高内聚低耦合的很重要的设计原则。
还是用Book作为例子,如果你的Book需要添加一个属性来表示新的状态(换句俗话就是你在数据库里加列了,数据库变化了)。如果你的Book类自己维护了自己的持久化状态,那么你就只需要修改Book类的持久化状态的方法。如果你使用的VS2005的话,使用重构功能一次性就能把所影响到的地方全部修改(java的用Eclipse也有同样的功能)。而如果没有封装的话。那么你可能需要改的还有BookManager,如果在其他地方还用到了Book,可能还有数不清的代码在等着你改。为什么会麻烦,因为没有了封装,类和类之间产生了耦合。
下一章我们会接下来谈继承(也包括接口的Implement)
所谓面向对象的编程、设计、思想。我们用大白话来说。
面向对象就是用 某物(对象),是什么(类),有什么(对象的状态),能干什么(方法)的方式来描述程序的方法。这就是面向对象。
面向对象的程序的特征,封装性:也就是某物状态的改变,必须是他自己的行为来改变。
打个比方,我(人类),有钱(有什么),你(人类),要找我借钱(能干什么)。于是
class Man()
{
private int money;
public int Money
{
get{return money}
set{money=value}
}
public void Borrow(Man Target,int Howmuch)
{
money+=Howmuch;
Target.Money-=Howmuch;
}
}
就是这个样子。这样子的写法是不对的,这样破坏类的封装性,我们绕过了Man的对象,直接去操作了对象的状态。这完全是强盗逻辑,跟你直接到我钱包里掏钱一样不可饶恕。所以,借钱这个动作还需要我来参与,你找我借钱,而我,要借给你钱。我们修改一下类的代码。我们给Man类增加一个Lend的方法,以封装在借出钱的时候对自身状态的改变。然后借钱的行为也要更改了。
class Man()
{
private int money;
public int Money
{
get{return money}
set{money=value}
}
public bool Lend(int Howmuch)
{
if(Howmuch<money)
{
money-=Howmuch;
return true;
}else
{
return false;
}
}
public void Borrow(Man Target,int Howmuch)
{
money+=Howmuch;
Target.Lend(Howmuch);
}
}
这样子的代码就是满足了封装性的原则,注意,封装既是特征,也是必须满足的条件,如果破坏了封装性原则那就是破坏了OO的原则。
这里回到了一个很实际的问题,失血模型为什么不OO。
我们定义了Book类,封装了Book的状态(属性)。如果我们用一个BookManager类去Save这本书(典型的失学模式的做法)。那么,我们在BookManager中如何保存?很多人在BookManager.Save里读取Book的属性,生成SQL,写数据库,返回执行结果。这样子OO么?不OO,因为这种做法完全破坏了封装性的原则。就跟之前借钱的例子一样。所以我们要在Book类增加一个Save方法,这个方法是用来维护Book类本身的状态的。而很多的ORM也能够给我们的类注入这类方法,使我们的的类具备持久化的能力。这样Book的属性,如何在数据库里存储,如何读取,如何删除都是Book自身来负责,因为在数据库里关于Book 的记录都是属于Book的状态,所以都需要Book自身来封装,使其透明化。
很多人在之前我写的Book.Save是否OO的话题里面说,觉得Book.Save方法仅仅是换了个位置。但是哪里知道,这个小小的改变却是一个原则性的问题。而至于双鱼座觉得在Save里加入上下文的参数更加符合实际情况,我个人觉的加和不加对Book类是否符合OO的原则没有太大的影响。
但是有和没有确是天壤之别了。
封装是保证系统的高内聚低耦合的很重要的设计原则。
还是用Book作为例子,如果你的Book需要添加一个属性来表示新的状态(换句俗话就是你在数据库里加列了,数据库变化了)。如果你的Book类自己维护了自己的持久化状态,那么你就只需要修改Book类的持久化状态的方法。如果你使用的VS2005的话,使用重构功能一次性就能把所影响到的地方全部修改(java的用Eclipse也有同样的功能)。而如果没有封装的话。那么你可能需要改的还有BookManager,如果在其他地方还用到了Book,可能还有数不清的代码在等着你改。为什么会麻烦,因为没有了封装,类和类之间产生了耦合。
下一章我们会接下来谈继承(也包括接口的Implement)
相关文章推荐
- 亚历山大同志:又见手把手系列-面向对象扫盲-通俗的OO第一弹-【封装】
- 面向对象扫盲-通俗的OO第一弹-【封装】
- 面向对象扫盲-通俗的OO第二弹-【续说封装】
- [转载]AAF灵便应用框架简介系列(6):休息一下,泛谈面向对象 Why OO+多层结构?
- [扫盲]利用架构实例解析面向对象的封装,多态,继承,接口,泛型
- 多线程开发扫盲系列第一编:进程与进程间通信
- 拖拽系列二、利用JS面向对象OOP思想实现拖拽封装
- 面向对象的javascript系列文章(2)封装——信息隐藏
- 拖拽系列二、利用JS面向对象OOP思想实现拖拽封装
- Atitit usbQb212 oo 面向对象封装的标准化与规范解决方案java c# php js
- Jser 设计模式系列之面向对象 - 接口封装与继承
- Atitit usbQb212 oo 面向对象封装的标准化与规范解决方案java c# php js
- 再次理解面向对象的第一大特征------封装
- 利用JS面向对象+模块化封装集AJAX请求、基本数据校验、URL参数截取等功能于一身的通用工具模块
- 黑马程序员----------面向对象之封装继承多态
- 黑马程序员—面向对象封装继承多态
- 前端学PHP之面向对象系列第一篇——类和对象
- 利用JS面向对象+模块化封装集AJAX请求、基本数据校验、URL参数截取等功能于一身的通用工具模块
- 微信公众号开发系列-Http请求封装基类
- 前端学PHP之面向对象系列第四篇——关键字