【大话设计模式】面向对象基础之山寨AS版(一)

A1.培训实习生

小菜的单位来了个大学实习生,叫史熙,开发部经理安排小菜有空教教他,小菜欣然接受。

“蔡老师,请多多关照。”史熙很诚恳。

“哈,不干当,我也刚毕业不久,比你大一届。以后叫我的名字吧,我叫蔡遥。”

“哦,那叫遥哥。”

寒暄部分略过

A2.类与实例

“我先问问你什么是类,对象是什么,类是什么?”小菜问道。

“准确的定义不知道,类大概就是对东西分类的意思。”史熙答的很勉强。

“啊,看来你是实实在在的菜鸟啊。一切事物皆对象,即所有的东西都是对象。对象是一个自包含的实体,用一组可识别的特性和行为来标识。面向对象编程,英文叫Object-Oriented Programming,其实就是针对对象来进行编程的意思。至于类,待会在将,现在我们用AS来模拟一个‘动物运动会’的小例子”

“动物运动会?有意思。”

“首先实现这样一个功能,点击一个‘猫叫’按钮,会输出‘喵’”。

“这个非常简单。”

Code

 

 

 “是,程序是编出来了,现在的问题就是,如果我们需要在另一个按钮种来让小猫叫一声,或者需要小猫多叫几声,怎么办?”

 

 “我知道你的意思,写个函数就可以解决了。其他需要‘猫叫’的地方都可以”

 

shout(猫叫)’放在舞台上合适吗?这就好比,居委会的公用电视放在你家,而别人家都没有,于是解放邻居都来你家看电视。你喜欢这样吗?”

 

Code

“很好,现在的问题是,你觉得这个‘

“这样好呀,邻居关系好了。不过这确实不是办法,公用电视应该放在居委会。”

“所以说,这‘猫叫’的函数应该放在一个更合适的地方,这就是‘类’。类就是具有相同的属性和功能的对象的抽象的集合,我们来看代码。”

 

class’是表示定义类的关键字,‘Cat’就是类的名称,‘shout’是类的方法。这里有两点要注意:一,类名称首字母要记得大写,多个单词则各个首字母大写;二,对外公开的方法需要用‘public’修饰符。”

 

Code

“这里的‘

“明白,那我要怎么用这个类呢?”

“很简单,只要将类实例化一下就可以了。”

“什么是实例化?”

“实例,就是一个真是的对象。比如我们都是‘人’,而你和我其实就是‘人’类的实例了。而实例化就是创建对象的过程,使用new关键字来创建。”

 

cat实例化后,等同于出生了一只小猫_cat,此时就可以让小猫_cat.shout()了。在如何需要小猫叫的地方都可以实例化它。”

 

Code

 

A.3构造方法

“下面,我们希望出生的小猫应该有个名字,比如叫‘咪咪’,当咪咪叫的时候,最好能说‘我的名字叫咪咪,喵’,此时我们考虑用构造方法。”

“构造方法?是什么?”

构造方法,又叫构造函数,其实就是对类进行初始化,构造方法与类同名,无返回值,在new的时候调用。”

“不对啊,在类当中没有写过构造方法Cat(),怎么调用啊?”

“问的好,实际情况是这样的,所有的类都有构造方法,如果你不编码则系统默认生成空的构造方法,若你有定义构造方法,那么默认的构造方法就会失效了。”

“那不是很好嘛,我们还要构造方法干什么?”

“刚不是说了吗,构造方法是为了对类进行初始化。比如我们希望每个小猫一诞生就有一个名字,那就应该写一个有参数的构造方法。”

Code
A.4
方法重载

“但是,如果我事先没有给小猫起名字,是不是这个实例就不能创建了?”史熙有问道。

“是的,有些父母刚生下孩子时,姓名没有起好是很正常的。就目前的代码来看,如果你写‘var _cat = new Cat();’的话,会直接报‘ArgumentError: Error #1063: Cat() 的参数数量不匹配。应该有 1 个,当前为 0 个。’原因就是必须要给小猫起个名字,如果真的不需要给小猫也要把小猫生出来,可以用‘方法重载’”

“方法重载?好像学过,具体如何说?”

方法重载提供了创建同名的多个方法的能力,但这些方法需要使用不同的参数类型或参数个数。在AS里没有真正意义上的重载,但我们可以给参数赋一个默认值,来实现重载的功能。”

var _cat = new Cat();’的话,就不会报错了。而猫叫时会是‘我的名字叫无名,喵’。”

Code

“哦,这样写的话,如果写‘

“对的,你觉得方法重载的好处是什么?”小菜问道。

“哈,我想应该是方法重载可以在不改变原方法的基础上,新增功能。”

 

A.6封装

“现在我们可以讲面向对象的三大特征之一‘封装’了。每个对象都包含它能进行操作所需要的所有信息,这个特性称为封装,因此对象不必依赖其他对象来完成自己的操作。这样的方法和属性包装在类中,通过类的实例来实现。”

“是不是刚才提炼出来Cat类,其实就是在做封装?”

“是呀,封装有很多好处,一,良好的封装能减少耦合;二,类内部的实现可以自由的修改,这是显而易见的,我们已经对Cat做了很大的改动;三,类具有清晰的对外接口,这其实指的是定义为publicshout方法。”

“封装的好处很好理解,比如刚才举的例子。我们的房子就是一个类的实例,室内的装饰与摆设只能被室内的居住着欣赏和使用,如果没有四面墙的遮挡,室内所有活动在外人面前一览无遗。有用有了封装,房屋内的所有摆设都可以随意的改变而不用影响他人。然而,如果没有门窗,一个包裹严严实实的黑箱子,即使他的空间再宽阔,也没有什么使用价值。房屋的门窗,就是封装对象暴露在外的属性和方法,专门供人进出,以及流通空气,带来阳光。”

“现在我需要增加一个狗叫的功能,就是添加一个按钮‘狗叫’,点击后会弹出‘我的名字叫XX汪汪’如何做?”

“很简单,仿造Cat加一个Dog类就可以了。”

 

OK了,小狗旺财也会叫了。”

 

Code

“这样就

“很好,但是你有没有发现,CatDog有非常相似的代码?90%都一样的。代码有大量重复不会是什么好事情。我们要用到面向对象的第二大特性‘继承‘”

A.7继承

“我们还是先离开软件编程,来想我们的动物常识,狗和猫都是哺乳动物,所以猫和狗就同样具备胎生,哺乳,恒温的特性。所以我们可以这样说,由于猫和狗是哺乳动物,所以猫和狗与哺乳动物是继承关系”小菜问道。

“哦,原来继承就是这个意思啊!”

“学习继承最好的是记住三句话,如果子类继承于父类,第一,子类拥有父类非private的属性和功能;第二,子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能;第三,子类还可以以自己的方式实现父类的功能(方法重写)。另外,除了privatepublic修饰符外,再讲一个protected修饰符。Protected表示继承时子类可以对基类有完全的访问权,也就是说,用protected修饰的类成员,对子类公开,但不对其他类公开。所以子类继承于父类,则子类就拥有了父类除private外的属性和功能。”

“方法重写是什么意思啊?”

“这个流到后面将多态的时候再讲,现在我们对比观察一下CatDog类。”

Cat

Code

 

Dog

Code

 

“我们发现大部分的代码都是相同的,所以我们建立一个Animal父类,显然猫和狗都是动物,我们把相同的代码尽量放到动物类中。”

Code

源码:http://www.brsbox.com/filebox/down/fc/345a849b80fc61075b53468169fb482c

“然后我们要写CatDog的代码,让它们继承Animal。这样重复的部分就不用再写了。子类从它的父类中继承的成员有方法,属性,事件,索引指示器。对于构造方法,在没有参数的情况下,会继承父类的构造函数。但如果构造方法包含一个参数,那么父类的构造函数不会被继承,只能被调用。对于调用父类的成员,我们使用super关键字。”

修改后的CatDog如下:

Cat

Code

Dog

Code

“此时客户端代码完全一样,没有受到影响,但重复的代码却因此减少了。”小菜说。

“差不多嘛,子类还是有些复杂,没简单到哪去啊?”史熙说。

“如果现在需要加,牛,羊,猪等多个类似的类,按你以前的方法就需要在复制三遍,也就是有五个类。如果我们需要改动起始的叫声次数,也就是让shoutNum3改为5,你需要改几个类?”

“我懂你的意思了,那需要改5个类,现在有了Animal,就只要改一个类就行了,继承可以使得重复减少。”

“说的好,不用继承的话,如果要修改功能,就必须在所有重复的方法中修改,代码越多,出错的几率就越大,而继承的优点就是,继承使得所有子类的公共部分都放在父类种,使得代码得到了共享,这就避免了重复,另外,继承可使得修改或扩展继承而来的实现都较为容易。”

“这么好,那以后就多多用继承。”

“多多用继承?我问你,CatDog的代码差不多,你有没有考虑,让Dog去继承Cat呢?这样的话,问题就来了。现在写的Cat只会叫,以后它还可以会抓老鼠,爬树等行为,让狗继承猫,就意味着狗也就会抓老鼠,会爬树。你觉得合理吗?”

“狗拿耗子,多管闲事。看来不能让狗继承猫,那样很容易造成不必要的麻烦。”

继承是有缺点,那就是父类变,则子类不得不变。让狗去继承于猫,显然不是什么好的设计,另外,继承会破坏包装,父类实现细节暴露给子类,这其实是增大了两个类之间的耦合性。”

“什么是耦合性?”

“简单的讲就是藕断丝连,两个类尽管分开,但那如果关系密切,一方的变化都会影响到另一方,这就是耦合性搞的表现,继承显然是一种类之前强耦合的关系。”

“明白了,那什么时候用继承才是比较合理的呢?”
“当两个类之间具备‘is-a’的关系时,就可以考虑用继承了,因为这表示一个类是另一个类的特殊种类,而当两个类之间是‘has-a’的关系时,这表示某个角色具有某一项责任,就不适合用继承了。比如人有两只手,手不能继承人;再比如飞机场有飞机,这飞机也不能去继承飞机场。”

OK,了解,谢谢遥哥!”

posted on 2009-01-10 13:21  拉登  阅读(2644)  评论(15编辑  收藏  举报

导航