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来实现“游泳”的方法就可以了。
    当然,我的方法并不是最好的,但是我认为,比直接在派生类中处理要好些。

时间: 2024-10-15 14:42:30

Delphi面向对象学习随笔五:一个真正的类的相关文章

Delphi面向对象学习随笔二 编写第一个类

作者:巴哈姆特(转载请注明出处并保持完整) 这回,我们讨论怎么编写我们自己的第一个类.    在编写我们自己的类之前,首先要说的是“类的继承”.    记得前几天,我在和一个朋友讨论类的特点的时候,他说:“类是可以没有构造方法的!”其实类必须有至少一个构造方法的,但是他的话也不全错,可以理解成“我们可以不实现我们自己的构造方法”.    当我们没有显式的为类编写一个构造方法的时候,那么,看上去,这个类好象是没有构造方法,但是实际上,就算你没有为这个类编写一个属于你自己的构造方法的时候,该类还是有

Delphi面向对象学习随笔九:后记

作者:巴哈姆特http://www.cnpack.org(转载时请注明出处并保持完整) 最后一篇了,呵呵!其实通过写这几篇笔记,也发现了我自己知识欠缺的部分.当然也通过各位高手的提点,让我把以前学习过的东西来了一次“体检”.    当然,错误也有,但是改了就还是好同志嘛,呵呵^_^ 随便介绍一下Delphi中的几个比较常用的类吧: TObject:    VCL中所有类的根类,即是说:VCL中所有的类/组件/控件都是从TObject中继承而来.TObject类中定义了基本的构造方法和析构方法.

Delphi面向对象学习随笔七:COM

作者:巴哈姆特http://www.cnpack.org(转载请注明出处并保持完整) 上一篇,我们介绍了接口.如果没有接触过COM对象的话,你会觉得接口真的很麻烦,也许会有:“还不如直接定义一个类更方便”的想法.    的确,没有经过COM封装的接口确实比较麻烦.在我看来,没有经过COM封装的接口似乎没有存在的意义.那么,什么是COM对象呢?它有什么优点呢?接下来开始对COM对象进行一个简单的介绍: COM是个二进制规范,它与实现的语言无关.这样,即使COM对象由不同的编程语言创建,运行在不同的

Delphi面向对象学习随笔三:overload与override

作者:巴哈姆特(转载请注明出处并保持完整)    首先,我想单独说明一下overload,为什么呢?因为overload和对象化关联不大,所以,我感觉单独提出来说明比较好.    我们都知道,在Pascal语法规则中,同一个UNIT里是不能存在两个同名的函数的,例如: function func(): Boolean; function func(const x: Char): Boolean; 这样是会出语法错误的,原因是因为标识符规则限制.但是问题出来了,如果我们需要几个功能相似但是参数不同

Delphi面向对象学习随笔八:物理封装

作者:巴哈姆特http://www.cnpack.org(转载请注明出去并保持完整)前面说过的封装其实是逻辑意义上的封装.逻辑封装是对某一特定逻辑功能模块的封装,这个特定逻辑功能块可以是一个类,当然也可以是一个包,他们都有自己的逻辑边界.另一种封装方式,我们通常叫它为物理封装:物理封装其实是具体实现代码的物理集合,他可以以bpl,dll,com+等形式体现. 逻辑封装里,对象的传递.数据共享与调用相对要简单的多,只要我们引用类所定义的单元(unit)就可以直接访问类中public和publish

Delphi面向对象学习(-)

Delphi面向对象学习随笔一:类与对象的关系作者:巴哈姆特http://www.cnpack.org(转载请注明出处并保持完整)工作几年了,总想做点总结,于是有了这篇东西,叫随笔吧呵    本文只是写写我对对象化的理解,主观成分很多,或许有错误,希望大家指正^_^    PS: 本文的演示代码均以Delphi 的Object Pascal语法为准. 类与对象的关系    要讨论类与对象的关系,需要先说一下什么是类,什么是对象. 类:    类.我认为是一个集合,和数学中的集合一样,是一类事物的

lua面向对象学习随笔 --类与实例

面向对象最基本的就是两点:类,对象. 但是lua是无类型的,要实现面向对象只能模拟实现. 其实他们都是表,多了个__index属性,就模拟出了实现“类和继承”的效果. 面对Lua千万别用c++的类来类比,不然会误入歧途! 它就是一个table而已下面一个典型的定义一个“类”的方式. class={} function class:new(o) local o=o or {} setmetatable(o,self) self.__index=self o:ctor() return o end

C++编程学习(五) C++ 存储类

一.auto 存储类 根据初始化表达式自动推断被声明的变量的类型. auto f=3.14; //double auto s("hello"); //const char* auto z = new auto(9); // int* auto x1 = 5, x2 = 5.0, x3='r';//错误,必须是初始化为同一类型 二.register 存储类 三.static 存储类 static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行

Vue 学习随笔五 - 简单项目设计

学一门技术的最好方法是用这个技术去做一件事情,现在规划一下我们这个DEMO的简单需求. 概述:做一个后台系统,实现简单的实体CRUD,以及跟前台的交互功能. UI:集成Bootstrap样式,实现简单后台的框架 后台:Springboot,使用Kotlin开发 需求:User的CRUD,User包括子类Car 就这么简单的功能,主要是用来学习VUE+Kotlin. 第一步:集成Bootstrap,毕竟不会做样式,真实项目有UI去操作,我们目前只需要简单的使用现成的框架即可. 1. 安装Boots