sizhefang 2009-12-16
虽然Ruby作为一种新语言,具有一些不同于其他语言的特性,比如没有函数,只有方法。但是它还是脱不了编程语言特有的性质。在这里我们将会为大家介绍有关Ruby多继承的相关实现方法。
一些程序语言(如C++和CLOS)提供了多重继承机制:一个类可以继承自多个超类。例如,一个House可能继承自一个Building类(连同Office和Hospital类一起)和Residence类(连同Apartment类一起)。尽管多重继承可能成为一种语言强有力的特征,但是由于它会增加该语言的复杂性和歧义,因此许多面向对象语言都没有加入它。
Ruby支持单继承。然而,它还提供了mixin-它提供了Ruby多继承的许多特征。一个mixin是一种"模块"类型。为此,你必须首先理解在Ruby中模块的含义。
在Ruby中,模块是一种把方法和常数分组的方式。它与类相似,但是一个模块没有实例并且也没有子类。也许解释模块的最好方法是举一个例子。假定你正在开发一个制造业应用程序。该程序需要存取大量的科学公式和常数,那么你可以或者是创建一个通用类来把这些放在其中或者是创建一个模块。模块的优点在于,在存取其中的公式时,根本没有任何实例扰乱所带来的烦恼。
现在,这些公式方法和常数可以被任何数目的其它类或其自身所使用:
irb(main):046:0> Formulas.force(10) =>98.0 irb(main):047:0≫ Formulas::ACCELERATION =≫9.8
注意,为了调用一个模块方法或使用一个模块常数,你必须使用类似于调用一个类方法的标志。为了调用一个模块方法,你需要使用模块类名,后面跟着一个点,再跟着模块方法名。为了引用模块常数,你可以使用模块名,后面跟着两个冒号,再跟着常数名。
除了作为方法和常数的"公共"应用以外,模块还可以帮助定义Ruby多继承。一个mixin是一个简单的"包括"有一个类定义的模块。当一个类包括一个模块时,所有的模块中的方法和常数都成为类的实例方法和常数。例如,假定上面定义的Formula模块作为一个mixin被添加到Rectangle类。为此,你要使用"include"关键字:
classRectangle includeFormulas end
现在,Rectangle的实例具有了它们可以使用的force和energy方法,并且Rectangle类能够访问常数ACCELERATION和LIGHTSPEED:
irb(main):044:0> classRectangle irb(main):045:1> includeFormulas irb(main):046:1>end =>Rectangle irb(main):047:0> Rectangle.new(4,5).force(10) =>98.0 irb(main):048:0> Rectangle::LIGHTSPEED =>299792458
这意味着,mixin给Ruby中的类带来了许多多重继承的优点,却避开了多重继承中存在的问题。
Ruby多继承控制流
象所有的程序语言一样,Ruby提供了一组控制流命令,这包括条件语句(if/else结构),case语句和循环语句(do,while和for),还提供了象Ada和Java等语言中的异常处理能力。下面是Ruby中的一些控制流语句的示例:
ifarea>100 "big" else "small" end caseheight |when1 |print"stubbyn" |when2..10#高度范围为2~10 |print"shortn" |when10..20#高度范围为2~10 |print"talln" |end aRect=Rectangle.new(4,6) whileaRect.area <100andaRect.height<10 aRect.doubleSize() end forelementin[2,9.8," somestring",Math::PI] #遍历对象集合 print"Thetypeis:"+ element.type.to_s+"n&" end
控制语句通常非常直接,但是如前面的case语句和for循环语句所显示的,Ruby借鉴了其它一些语言特征和普通的面向对象的特性。
异常处理类似于Java中的"try...catch...finally"语句。在Ruby中,它们更改为"begin...rescue...ensure"语句:
begin #实现一些事情 rescue ##处理错误 ensure #做一些清理工作, 如关闭一个打开的文件等 end
为了在你的Ruby多继承代码中引发一个异常,你只需要简单地调用raise方法:
ifarea<0 raise elseifarea>0andarea<10 raise"Rectangletoosmall" elseifarea>100 raiseTooBigException "Rectangletoobig" end
第一个raise调用创建一个RuntimeError。第二个raise创建一个显示一条消息的RuntimeError。最后一个raise调用一个TooBigException的新实例(由它创建一个粗略定义的错误),并设置它的适当消息。
一个Ruby多继承小程序