CnPack 开源软件项目 - Delphi面向对象学习随笔五:一个真正的类
  网站首页 下载中心 每日构建 文档中心 捐助我们 开发论坛 关于我们 致谢名单 English


 Google 搜索

内容: 
 最新下载


 
CnWizards 1.5.1.1219
[2024-11-03]

 
CnVCL 组件包 20241103
[2024-11-03]

 
CnPack 密码算法库 20241103
[2024-11-03]
  每日构建版下载
  专家包时间线
 项目相关链接


 
CnPack GitHub 首页
GIT 使用说明
申请加入 CnPack
CnPack 成员名单
 网站访问量

今日首页访问: 217
今日页面流量: 1197
全部首页访问: 5317061
全部页面流量: 21461469
建站日期: 2003-09-01

 
Delphi面向对象学习随笔五:一个真正的类
 
CnPack 开源软件项目 2008-06-22 23:34:06

Delphi面向对象学习随笔五:一个真正的类
作者:巴哈姆特
(转载请注明出去并保持完整)

写在前面的话:
    本篇笔记完全属于我的个人主观观点,如有错误请指正^_^
  类的定义:
    首先,我想说的是,类并不是一些变量和函数简单的“拼凑”出来的。类应该是对于一个事物的抽象描述,而不是一个动作的抽象描述。怎么讲呢?
    比如说:鞋子是一个事物,我们可以把它的特点抽象出来,并用计算机语言去描述成为一个类,而鞋子又分了凉鞋、皮鞋等,那么“凉鞋”和“皮鞋”则是“鞋子”的派生类。它们看上去是非常自然的。
    那么,现在我有另外一个类,“初始化数据库”类,这个类看上去是非常别扭的;因为它看上去更像是一个动作。而这个“初始化数据库”类则更像是其他类中的一个“初始化数据库”方法。
  编写类应该注意的问题:
    一、尽可能的限制类的成员的可访问性:当你拿不准一个方法是否应该对外公开的时候,应该首先考虑定义为私有方法。
    二、尽量避免暴露无需外界关心的实现细节:例如,汽车的发动机原理是不需要开汽车的司机知道的。
    三、保持类本身的独立性与健壮性,不应该对类的使用者有任何想当然的假设或强制的要求:比如如果写了一个类,其某个属性不能是负值,则应该在类内部显式处理负值的情况,并给出适当的出错处理,而不能在注释中写上“{在创建类以后,请初始化xx属性为正数,如果初始化为负数的话类将会崩溃},”这样的将责任推给使用者的宣言。
    四、让代码阅读比编写更方便:因为代码的阅读次数比编写次数要多的多。
    五、尽可能的降低类与类之间的耦合度:除非是有包含关系,如果是平等关系的类,应该避免在类中的方法依赖于其他类中的属性或方法。
  遇见问题时的处理方法:
    假设、我们有一个基类“鸟类”(TBird),类中有一个通用方法“飞”(Fly)。并且为这个类派生了一些子类“海鸥”(TGull)等、这些看起来似乎很正常,但是当我们在定义“鸵鸟”(TOstrich)的时候,发现鸵鸟其实是不会飞的,但是他跑起来却很快,那么有人就会简单的覆盖掉基类的(Fly)方法,并不给出实现,而另外添加一个跑(Run)方法。
    这样其实是不好的,当然我并不是让大家对以后的事做出预计,我想说的是,在发现父类与子类在某个方法发生冲突的时候,我们应该从源头抓起,我认为一个更好的方案是:
    把基类TBird中的Fly方法改为DoAction(动作)方法,并指定为抽象方法,然后添加两个派生类TFlyBird(飞行的鸟)和TRunBird(跑步的鸟)。
    在TFlyBird类中覆盖DoAction方法实现“飞翔”的动作,并添加public方法Fly,在Fly中调用DoAction来实现“飞翔”这一方法;
    在TRunBird类中覆盖DoAction方法实现“跑步”的动作,并添加public方法Run,在Run中调用DoAction来实现“跑步”这一方法。
    然后更改TGull等具有Fly方法(即飞行的鸟)的父类为TFlyBird,更改TOstrich等不具有Fly(即跑步的鸟)的父类为TRunBird。
    那么,就算哪天我们又发现了一种会游泳的鸟,那么也只需要为TBird类派生一个TSwimBird(游泳的鸟)子类,并添加一个公有方法Swim让其调用DoAction来实现“游泳”的方法就可以了。
    当然,我的方法并不是最好的,但是我认为,比直接在派生类中处理要好些。



本文已阅读 11615 次
来自: CnPack 开源软件项目

上一主题 | 返回上级下一主题

相关主题:


版权所有(C) 2001-2024 CnPack 开发组 网站编写:Zhou Jinyu