Ruby的多继承

一些程序语言(如C++和CLOS)提供了多重继承机制:一个类可以继承自多个超类。例如,一个House可能继承自一个Building类(连同Office和Hospital类一起)和Residence类(连同Apartment类一起)。尽管多重继承可能成为一种语言强有力的特征,但是由于它会增加该语言的复杂性和歧义,因此许多面向对象语言都没有加入它。

Ruby支持单继承。然而,它还提供了mixin-它提供了多继承的许多特征。一个mixin是一种"模块"类型。为此,你必须首先理解在Ruby中模块的含义。

在Ruby中,模块是一种把方法和常数分组的方式。它与类相似,但是一个模块没有实例并且也没有子类。也许解释模块的最好方法是举一个例子。假定你正在开发一个制造业应用程序。该程序需要存取大量的科学公式和常数,那么你可以或者是创建一个通用类来把这些放在其中或者是创建一个模块。模块的优点在于,在存取其中的公式时,根本没有任何实例扰乱所带来的烦恼。

module Formulas
  ACCELERATION = 9.8
  LIGHTSPEED = 299792458
  def energy (mass)
    mass*(LIGHTSPEED**2)
  end
  def force (mass)
    mass*ACCELERATION
  end
end

现在,这些公式方法和常数可以被任何数目的其它类或其自身所使用:

irb(main):046:0>Formulas.force(10)
=>98.0
irb(main):047:0≫Formulas::ACCELERATION
=≫ 9.8

注意,为了调用一个模块方法或使用一个模块常数,你必须使用类似于调用一个类方法的标志。为了调用一个模块方法,你需要使用模块类名,后面跟着一个点,再跟着模块方法名。为了引用模块常数,你可以使用模块名,后面跟着两个冒号,再跟着常数名。

除了作为方法和常数的"公共"应用以外,模块还可以帮助定义多重继承。一个mixin是一个简单的"包括"有一个类定义的模块。当一个类包括一个模块时,所有的模块中的方法和常数都成为类的实例方法和常数。例如,假定上面定义的Formula模块作为一个mixin被添加到Rectangle类。为此,你要使用"include"关键字:

class Rectangle
  include Formulas
end

现在,Rectangle的实例具有了它们可以使用的force和energy方法,并且Rectangle类能够访问常数ACCELERATION和LIGHTSPEED:

irb(main):044:0> class Rectangle
irb(main):045:1> include Formulas
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中的类带来了许多多重继承的优点,却避开了多重继承中存在的问题。

发布了42 篇原创文章 · 获赞 6 · 访问量 9万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章