从魔兽中的英雄设计机制来窥探面向对象的思想
疯牛涕淌是从零二年夏天开始玩魔兽的,到现在也算只老鸟了吧。你是不是也是个魔兽迷呀?不过话说回来,玩物可不能丧志的,不知你在玩过这些游戏的时候,是不是和我一样也思考些别的东西,比如软件的设计思想等等什么的。呵呵,别骂我变态
好好好言归正传(故意咳嗽两下)!领会面向对象,关键是这三个基本的概念:封装、继承和多态性。我按照顺序分别讲解一下。
封装是什么呢?很简单,在你写代码的时候,你一定有过把一个变量声明为Private的经历吧?你不希望外部世界来污染它——这就是封装。在一个类中,它的内部变量(你也可以直观地把它们认为是属性)默认下是隐藏于外部世界的。如果你要操纵一个类,那么,请直接告诉他你想让它做些什么吧——至于它是怎么做到的,这个你没权利了解的。
呼呼,你在玩魔兽的时候,英雄的那些属性,譬如生命值、魔法值、攻击力值等,其实就是被封装在每个英雄的类里的。那我们为什么可以读取这些属性呢?那是因为这些类提供给了我们读取属性的接口。譬如你想读取或设置月之女祭司的生命值,你其实在不知不觉中经历了下面几个步骤的。你先是对月之女祭司说:“月之女祭司,我想看下你的生命力的值,可否?”她说:“这个嘛,我时刻都把我当前的生命力的值公布在我的状态栏上,你自己看去吧。至于我是怎么把我的这些值公布出来的,你无权知道。”然后忘形的你竟然得寸进尺,想从状态栏上直接修改她的生命力值。她会十分气恼地说:“但是我不提供这样的服务!你得让我喝月井的水才行呀!”哦~~~喝月亮井的水便是另一个和生命值挂了钩的方法呀,你可以通过这个接口修改生命力值了。这样的接口起到了约束使用者的目的,避免了数据被非法污染,实现了封装的初衷。
象上面的读取属性的方法也被叫做“只读方法”,同样地也有“只写方法”,一样样的道理,我懒得赘述了。需要说的是,并不是所有的内部属性都拥有通向外界的接口。记住,类的设计总是要让它在它的使用者看起来更简单,因此如果某个类的编写者认为其中某个数据成员没有必要被使用这个类的人感知到它的存在,那么如果那天他没有喝太多酒的话,他就不会对那个数据提供任何相应的接口。这样,这个属性就彻底地被封装起来了。
当然没有人会阻止你把变量声明成Public,但是也绝没有人推荐你这么做,所以这样声明之前请你确信这样是必要的。你可以试想一下,如果月之女祭司把控制她的生命力值的权利完全地公诸于众,那么游戏还有什么公平性可言呢?
“总款哦……”你茅厕顿开,“类就是这么一回事呀!把它的数据隐藏,而通过它公开的方法来实现其和类的使用者的互动。魔兽中那么多英雄,每个族四个,加上六个中立英雄,二十二个英雄就是二十二个类哈!”那我会摸着你的头说:“对,你真是可以这么认为的。Hmmm,都有四种魔法,都有生命值、魔法值、最大攻击力值、最小攻击力值、防御力值,etc。那么二十二个英雄,我们都可以慢慢地写,没问题……”
这时你突然用力推开了我的手:“且慢!既然二十二个类有这么多公用的属性和方法,那你干屌不试着直接写出一个抽象的英雄类呢?”我说你狂有思想的,因为这就是当初引进继承的滥觞。不单单魔兽中的英雄如是,你细细观察一下,生活中和机器世界里也充斥着这样的例子。如果不利用它们的派生继承的关系,而冲动地将每个类都设计成一个独立的类,那么你将要重复写多少行代码?这么一想来似乎有点恐怖吧?所以我们要继承,因为这样的机制在很大程度上提高了我们开发软件的效率。
让我们把话题再拉回到我们的前面提到的英雄抽象类上。我猜你不太敢想象这样的类被创建成实例会是什么样是么?呵呵,反正我是不敢想象的。因为我一试图这么做,我头脑中总会浮现出一只脊椎动物的受精卵,红红软软的一坨,鬼知道它成熟后会是什么屌样,反正好恶的样子。
请你在这里稍停顿思考一下……12秒钟吧……
如果你够聪明的话,你一定会追问我:“那么,既然是个不愿意被实现的抽象基类,那么这个类里面的方法要怎么写?比如说UseUltimateSkill……”嗯,问得好!既然我们不愿意抽象类被创建成实例,那么很简单,我们也不必费神去写代码了,但是我们在这个类的方法前签个单方协议——我们姑且称之为“MustInherit”协议吧。协议正文是这么写的:“你要继承我是吗?没问题!但是,你必须自己填充你对我的这个方法的实现。否则,你就别指望继承我啦!”
于是每个英雄便急着各显其神通了。恶魔猎手说:“我最想耍流氓,就让我来个流氓大变身好了!”大法师在一旁诡异地哼了一声:“你猛,老子俺惹不起躲得起。俺就瞬间转移吧嘿嘿。”死亡骑士也不甘示弱:“我最高尚,我要让别人实现起死回生!”这可把老牛酋长乐坏了:“这年头高尚早不时髦了,看我让我自己起死回生的本事,还全自动的呢!”……于是二十二个英雄就这样拥有了自己的魔法——一个方法名,真真是千姿百态啊!
这时你呆滞地抹去嘴角的口水问道:“哦,涕淌兄,这不会就是多态性吧?”
我说废话小子哈哈。
http://dev.csdn.net/user/GnuDoyng
转载于:https://www.cnblogs.com/aaronlly/archive/2005/04/26/145595.html
从魔兽中的英雄设计机制来窥探面向对象的思想相关推荐
- 深度学习中的注意力机制(三)
作者 | 蘑菇先生 来源 | NewBeeNLP原创出品 深度学习Attenion小综述系列: 深度学习中的注意力机制(一) 深度学习中的注意力机制(二) 目前深度学习中热点之一就是注意力机制(Att ...
- 一篇了解NLP中的注意力机制
文章发布于公号[数智物语] (ID:decision_engine),关注公号不错过每一篇干货. 转自 | AI小白入门(公众号ID: StudyForAI) 作者 | yuquanle,985在读硕 ...
- 跟着 Event loop 规范理解浏览器中的异步机制
原文发自我的 GitHub blog,欢迎关注 前言 我们都知道 JavaScript 是一门单线程语言,这意味着同一事件只能执行一个任务,结束了才能去执行下一个.如果前面的任务没有执行完,后面的任务 ...
- 浅说Java中的反射机制(一)
在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...
- 探索Android中的Parcel机制(上)
一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化--,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...
- Js中的callback机制
http://www.awflasher.com/blog/archives/906 Js中的callback机制,即回调,可以这么形象的来理解,一个button存在这里,我们可以add一个actio ...
- 探索Android中的Parcel机制(上) .
一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化--,其作用是能将数据对象存入字节流当中,在需要时重新生成对象.主要应用是利用外部存储设备保存对象状态, ...
- 百分点认知智能实验室:NLP模型开发平台在舆情分析中的设计和实践(下)
编者按 NLP模型开发平台是以快速打造智能业务为核心目标,无需机器学习专业知识,模型创建-数据上传-数据标注(智能标注.数据扩充)-模型训练-模型发布-模型校验全流程可视化便捷操作,短时间内即可获得高 ...
- 【NLP】四万字全面详解 | 深度学习中的注意力机制(四,完结篇)
作者 | 蘑菇先生 知乎 | 蘑菇先生学习记 深度学习Attention小综述系列: 四万字全面详解 | 深度学习中的注意力机制(一) 四万字全面详解 | 深度学习中的注意力机制(二) 四万字全面详解 ...
最新文章
- [Poetize6] IncDec Sequence
- JVM常用启动参数大全(附带解释)
- oracle数据库两表数据比较
- imeoptions android,软键盘小记Android:imeOptions
- python_10 迭代器和生成器
- sp_lock显示的信息说明
- css实现在一行显示多余部分显示省略号
- PLC单按钮启停电路与特殊辅助继电器
- 关于另类BT下载的想法
- 动手学深度学习(tensorflow)---学习笔记整理(五、过拟合和欠拟合相关问题篇)
- 关于技术人员的非技术能力
- Navicat注释乱码
- CTF-Crypto学习1(软件加壳、反汇编、Babe64、Rijndael密码算法)
- 多组两两比较用什么检验方法_手把手教你多组独立样本的非参数检验及两两比较...
- 解决微信ios端+sendReq: not found
- E-R图与数据库模型学习心得
- javaweb网页上传图片并显示在页面上,并在服务端存到磁盘(base64编码解码)
- 请你谈谈为什么分布式系统需要限流器
- 设置.env.development无效
- Java大数据基础——day01