A1.培训实习生
小菜的单位来了个大学实习生,叫史熙,开发部经理安排小菜有空教教他,小菜欣然接受。
“蔡老师,请多多关照。”史熙很诚恳。
“哈,不干当,我也刚毕业不久,比你大一届。以后叫我的名字吧,我叫蔡遥。”
“哦,那叫遥哥。”
寒暄部分略过…
A2.类与实例
“我先问问你什么是类,对象是什么,类是什么?”小菜问道。
“准确的定义不知道,类大概就是对东西分类的意思。”史熙答的很勉强。
“啊,看来你是实实在在的菜鸟啊。一切事物皆对象,即所有的东西都是对象。对象是一个自包含的实体,用一组可识别的特性和行为来标识。面向对象编程,英文叫Object-Oriented Programming,其实就是针对对象来进行编程的意思。至于类,待会在将,现在我们用AS来模拟一个‘动物运动会’的小例子”
“动物运动会?有意思。”
“首先实现这样一个功能,点击一个‘猫叫’按钮,会输出‘喵’”。
“这个非常简单。”
}
}
“很好,现在的问题是,你觉得这个‘
“这样好呀,邻居关系好了。不过这确实不是办法,公用电视应该放在居委会。”
“所以说,这‘猫叫’的函数应该放在一个更合适的地方,这就是‘类’。类就是具有相同的属性和功能的对象的抽象的集合,我们来看代码。”
}
}
“这里的‘
“明白,那我要怎么用这个类呢?”
“很简单,只要将类实例化一下就可以了。”
“什么是实例化?”
“实例,就是一个真是的对象。比如我们都是‘人’,而你和我其实就是‘人’类的实例了。而实例化就是创建对象的过程,使用new关键字来创建。”
“
A.3构造方法
“下面,我们希望出生的小猫应该有个名字,比如叫‘咪咪’,当咪咪叫的时候,最好能说‘我的名字叫咪咪,喵’,此时我们考虑用构造方法。”
“构造方法?是什么?”
“构造方法,又叫构造函数,其实就是对类进行初始化,构造方法与类同名,无返回值,在new的时候调用。”
“不对啊,在类当中没有写过构造方法Cat(),怎么调用啊?”
“问的好,实际情况是这样的,所有的类都有构造方法,如果你不编码则系统默认生成空的构造方法,若你有定义构造方法,那么默认的构造方法就会失效了。”
“那不是很好嘛,我们还要构造方法干什么?”
“刚不是说了吗,构造方法是为了对类进行初始化。比如我们希望每个小猫一诞生就有一个名字,那就应该写一个有参数的构造方法。”
);
trace(_cat.shout());
}
A.4
方法重载
trace(_cat.shout());
}
“但是,如果我事先没有给小猫起名字,是不是这个实例就不能创建了?”史熙有问道。
“是的,有些父母刚生下孩子时,姓名没有起好是很正常的。就目前的代码来看,如果你写‘var _cat = new Cat();’的话,会直接报‘ArgumentError: Error #1063: Cat() 的参数数量不匹配。应该有 1 个,当前为 0 个。’原因就是必须要给小猫起个名字,如果真的不需要给小猫也要把小猫生出来,可以用‘方法重载’”
“方法重载?好像学过,具体如何说?”
“方法重载提供了创建同名的多个方法的能力,但这些方法需要使用不同的参数类型或参数个数。在AS里没有真正意义上的重载,但我们可以给参数赋一个默认值,来实现重载的功能。”
var _cat = new Cat();’的话,就不会报错了。而猫叫时会是‘我的名字叫无名,喵’。”
}
}
“哦,这样写的话,如果写‘
“对的,你觉得方法重载的好处是什么?”小菜问道。
“哈,我想应该是方法重载可以在不改变原方法的基础上,新增功能。”
A.6封装
“现在我们可以讲面向对象的三大特征之一‘封装’了。每个对象都包含它能进行操作所需要的所有信息,这个特性称为封装,因此对象不必依赖其他对象来完成自己的操作。这样的方法和属性包装在类中,通过类的实例来实现。”
“是不是刚才提炼出来Cat类,其实就是在做封装?”
“是呀,封装有很多好处,一,良好的封装能减少耦合;二,类内部的实现可以自由的修改,这是显而易见的,我们已经对Cat做了很大的改动;三,类具有清晰的对外接口,这其实指的是定义为public的shout方法。”
“封装的好处很好理解,比如刚才举的例子。我们的房子就是一个类的实例,室内的装饰与摆设只能被室内的居住着欣赏和使用,如果没有四面墙的遮挡,室内所有活动在外人面前一览无遗。有用有了封装,房屋内的所有摆设都可以随意的改变而不用影响他人。然而,如果没有门窗,一个包裹严严实实的黑箱子,即使他的空间再宽阔,也没有什么使用价值。房屋的门窗,就是封装对象暴露在外的属性和方法,专门供人进出,以及流通空气,带来阳光。”
“现在我需要增加一个狗叫的功能,就是添加一个按钮‘狗叫’,点击后会弹出‘我的名字叫XX汪汪’如何做?”
“很简单,仿造Cat加一个Dog类就可以了。”
trace(_dog.shout());
}
}
“这样就
“很好,但是你有没有发现,Cat和Dog有非常相似的代码?90%都一样的。代码有大量重复不会是什么好事情。我们要用到面向对象的第二大特性‘继承‘”
A.7继承
“我们还是先离开软件编程,来想我们的动物常识,狗和猫都是哺乳动物,所以猫和狗就同样具备胎生,哺乳,恒温的特性。所以我们可以这样说,由于猫和狗是哺乳动物,所以猫和狗与哺乳动物是继承关系”小菜问道。
“哦,原来继承就是这个意思啊!”
“学习继承最好的是记住三句话,如果子类继承于父类,第一,子类拥有父类非private的属性和功能;第二,子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能;第三,子类还可以以自己的方式实现父类的功能(方法重写)。另外,除了private和public修饰符外,再讲一个protected修饰符。Protected表示继承时子类可以对基类有完全的访问权,也就是说,用protected修饰的类成员,对子类公开,但不对其他类公开。所以子类继承于父类,则子类就拥有了父类除private外的属性和功能。”
“方法重写是什么意思啊?”
“这个流到后面将多态的时候再讲,现在我们对比观察一下Cat和Dog类。”
Cat类
}
}
}
Dog类
}
}
}
“我们发现大部分的代码都是相同的,所以我们建立一个Animal父类,显然猫和狗都是动物,我们把相同的代码尽量放到动物类中。”
}
}
}
源码:http://www.brsbox.com/filebox/down/fc/345a849b80fc61075b534681
“然后我们要写Cat和Dog的代码,让它们继承Animal。这样重复的部分就不用再写了。子类从它的父类中继承的成员有方法,属性,事件,索引指示器。对于构造方法,在没有参数的情况下,会继承父类的构造函数。但如果构造方法包含一个参数,那么父类的构造函数不会被继承,只能被调用。对于调用父类的成员,我们使用super关键字。”
修改后的Cat和Dog如下:
Cat类
类
}
}
}
Dog
}
}
}
“此时客户端代码完全一样,没有受到影响,但重复的代码却因此减少了。”小菜说。
“差不多嘛,子类还是有些复杂,没简单到哪去啊?”史熙说。
“如果现在需要加,牛,羊,猪等多个类似的类,按你以前的方法就需要在复制三遍,也就是有五个类。如果我们需要改动起始的叫声次数,也就是让shoutNum有3改为5,你需要改几个类?”
“我懂你的意思了,那需要改5个类,现在有了Animal,就只要改一个类就行了,继承可以使得重复减少。”
“说的好,不用继承的话,如果要修改功能,就必须在所有重复的方法中修改,代码越多,出错的几率就越大,而继承的优点就是,继承使得所有子类的公共部分都放在父类种,使得代码得到了共享,这就避免了重复,另外,继承可使得修改或扩展继承而来的实现都较为容易。”
“这么好,那以后就多多用继承。”
“多多用继承?我问你,Cat和Dog的代码差不多,你有没有考虑,让Dog去继承Cat呢?这样的话,问题就来了。现在写的Cat只会叫,以后它还可以会抓老鼠,爬树等行为,让狗继承猫,就意味着狗也就会抓老鼠,会爬树。你觉得合理吗?”
“狗拿耗子,多管闲事。看来不能让狗继承猫,那样很容易造成不必要的麻烦。”
“继承是有缺点,那就是父类变,则子类不得不变。让狗去继承于猫,显然不是什么好的设计,另外,继承会破坏包装,父类实现细节暴露给子类,这其实是增大了两个类之间的耦合性。”
“什么是耦合性?”
“简单的讲就是藕断丝连,两个类尽管分开,但那如果关系密切,一方的变化都会影响到另一方,这就是耦合性搞的表现,继承显然是一种类之前强耦合的关系。”
“明白了,那什么时候用继承才是比较合理的呢?”
“当两个类之间具备‘is-a’的关系时,就可以考虑用继承了,因为这表示一个类是另一个类的特殊种类,而当两个类之间是‘has-a’的关系时,这表示某个角色具有某一项责任,就不适合用继承了。比如人有两只手,手不能继承人;再比如飞机场有飞机,这飞机也不能去继承飞机场。”
“OK,了解,谢谢遥哥!”
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:【大话设计模式】面向对象基础之山寨AS版(一) - Python技术站