站长百科 | 数字化技能提升教程 数字化时代生存宝典
首页
数字化百科
电子书
▼
建站程序
开发
服务器
办公软件
开发教程
▼
服务器教程
软件使用教程
运营教程
热门电子书
▼
CSS教程
WordPress教程
导航
程序频道
推广频道
网赚频道
人物频道
网站程序
网页制作
云计算
服务器
CMS
论坛
网店
虚拟主机
cPanel
网址导航
WIKI使用导航
WIKI首页
热点词条
最新资讯
网站程序
站长人物
页面分类
使用帮助
编辑测试
创建条目
网站地图
站长百科导航
站长百科
主机侦探
IDCtalk云说
跨境电商导航
WordPress啦
站长专题
网站推广
网站程序
网站赚钱
虚拟主机
cPanel
网址导航专题
云计算
微博营销
虚拟主机管理系统
开放平台
WIKI程序与应用
美国十大主机
编辑“
Ruby-类,对象,变量
”(章节)
人物百科
|
营销百科
|
网赚百科
|
站长工具
|
网站程序
|
域名主机
|
互联网公司
|
分类索引
跳转至:
导航
、
搜索
警告:
您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您
登录
或
创建
一个账户,您的编辑将归属于您的用户名,且将享受其他好处。
反垃圾检查。
不要
加入这个!
== 继承和消息 == 继承允许你创建一个类,这个类是另一个类的改进版或是特殊版。比如说我们的点唱机有歌曲的概念,我们把它抽象成Song类,后来,市场发展了,我们被告知需要提供对卡拉OK的支持,一支卡拉OK歌曲本质上还是一首歌(它没有歌声,不过这和我们没什么关系),不过它多了和时间同步的歌词,当我们的点唱机演奏一首卡拉OK时,歌词应该随着音乐的时间在屏幕上滚动过去。 <br> 一个解决办法是定义一个新类,KaraokeSong,就像Song类,不过多了歌词。<br> class KaraokeSong < Song<br> def initialize(name, artist, duration, lyrics)<br> super(name, artist, duration)<br> @lyrics = lyrics<br> end<br> end <br> 在这个类的定义中,"<Song"所在的行表示KaraokeSong是Song的子类。(不要惊奇,这就是说Song类是KaraokeSong类的父类。人们常常谈论父子关系,如此说来KaraokeSong的父亲就是Song了)。暂时不要管initialize方法,我们稍候再讨论super的用法。<br> 我们来创建一个KaraokeSong对象,检查我们代码的运行情况。(在目前的系统中,歌词存放在一个包含文本和时间信息的对象中,不过为了测试我们的代码,在这里我们使用字符串来存储,这是我们这种无类型语言的又一大优势----在我们运行代码前不必定义任何东西)。<br> aSong = KaraokeSong.new("My Way", "Sinatra", 225, "And now, the...") <br> aSong.to_s >> "Song: My Way--Sinatra (225)" <br> 不错,正常运行,可是为什么to_s方法不显示歌词呢?<br> 这取决于你传送信息给一个对象时Ruby是如何决定哪个方法被调用的。当Ruby编译到aSong.to_s时,它并不知道to_s的真正位置,它忽略过去等到程序运行的时候再处理,到那时,Ruby首先在aSong的类中查找,如果它的类中实现了与这个消息同名的方法,这个方法就会被执行,否则,Ruby将在它的父类中寻找该方法,然后是祖父类…沿着族谱向上寻找,如果到最后都没有发现这个方法,Ruby将返回一个错误信息。(事实上,你可以截取这个错误信息,以便在运行时修正错误,355页的Object#method_missing有详细论述。)<br> 现在回到我们的例子上。当我们给KaraokeSong类的对象aSong发送to_s信息时,Ruby首先在KaraokeSong类中寻找to_s方法,但没有找到,然后在其父类Song中寻找,结果找到了,to_s方法是我们在18页定义的。现在知道为什么to_s不显示歌词了,原来to_s根本不知道有歌词这回事。<br> 我们完善一下代码来实现KaraokeSong#to_s,有好几种办法可以完成这项任务,我们先从一个不好的开始。我们从Song类中把to_s方法的代码拷贝过来,再加上歌词。<br> class KaraokeSong <br> # ... <br> def to_s <br> "KS: #{@name}--#{@artist} (#{@duration}) [#{@lyrics}]" <br> end <br> end v aSong = KaraokeSong.new("My Way", "Sinatra", 225, "And now, the...") <br> aSong.to_s ? "KS: My Way--Sinatra (225) [And now, the...]" <br> 我们终于成功显示了@lyrics这个实例变量,为了这个目的子类直接访问了父类的实例变量,那么为什么说这不是个好办法呢?<br> 这和好的编程风格(还有去耦)有关。我们在父类的内部闲逛,结果是我们的子类实现起来要和父类很紧密。如果我们把Song的持续播放时间改成用微秒做单位,那样KaraokeSong就会显出一些古怪的值,一首‘My Way’的卡拉OK持续要3750分钟,这会让人疯掉的。<br> 每个类都应该只处理自身的内部状态,当KaraokeSong#to_s被调用的时候,我们让它调用父类的to_s方法来处理子类中的歌词细节,它会添加歌词信息然后返回结果,这里的诀窍是Ruby的关键字super。若你不带参数调用super,Ruby发送一个消息给当前类的父类,请求父类调用与当前方法同名的方法,并且把我们传递给当前方法的参数传递过去。现在让我们实现我们新的增强版to_s。<br> class KaraokeSong < Song <br> # Format ourselves as a string by appending <br> # our lyrics to our parent's #to_s value. <br> def to_s <br> super + " [#{@lyrics}]" <br> end <br> end <br> aSong = KaraokeSong.new("My Way", "Sinatra", 225, "And now, the...") <br> aSong.to_s ? "Song: My Way--Sinatra (225) [And now, the...]" <br> 我们明确地告诉Ruby,KaraokeSong是Song类的一个子类,但是我们没有指定Song自身的父类。如果在定义类的时候你不指定一个父类,Ruby就默认指定Object类为其父类(看到Java的影子了吗)。这意味着所有的类都把Object类当作是它们的祖先,Object类的实例方法基本上适用于Ruby的每个类。在18页我们说过to_s方法对所有的对象都适合,现在应该明白为什么了,因为to_s正是Object类中大约35个实例方法中的一个,Object类中的方法列表在351页。<br>
摘要:
请注意,您对站长百科的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。
您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅
Wordpress-mediawiki:版权
的细节)。
未经许可,请勿提交受版权保护的作品!
取消
编辑帮助
(在新窗口中打开)