2013-08-07 55 views
1

我一直在做一些'猴子補丁'(ahem請原諒我超人補丁),像這樣,將下面的代碼和更多的文件添加到文件中,在我"#{Rails.root}/initializers/"文件夾:繼承自**其他**類,而不是實際的父類

module RGeo 
module Geographic 
class ProjectedPointImpl 
    def to_s 
    coords = self.as_text.split("(").last.split(")").first.split(" ") 
    "#{coords.last}, #{coords.first}" 
    end# of to_s 
    def google_link 
    url = "https://maps.google.com/maps?hl=en&q=#{self.to_s}" 
    end 
end# of ProjectedPointImpl class 
end# of Geographic module 
end 

我最終意識到,有兩個不同的_Point_情況下,我想利用這些方法(它們都具有相同的格式,即熟知文本(WKT)字符串)並將上述兩種方法的精確副本添加到某個RGeo::Geos::CAPIPointImpl類空間中。

我的話,在我年輕,沒有經驗的方式,想着幹後(不要重複自己)的原則,着手創建一個特設類,我認爲我也許可以從兩個

繼承
class Arghhh 
    def to_s 
    coords = self.as_text.split("(").last.split(")").first.split(" ") 
     "#{coords.last}, #{coords.first}" 
    end# of to_s 

    def google_link 
    url = "https://maps.google.com/maps?hl=en&q=#{self.to_s}" 
    end 
end 

,並告訴我的課,從它繼承,即:ProjectedPointImpl < Arghhh

我被及時迴應了紅寶石這個錯誤,當我停下來,然後嘗試重新加載我的rails控制檯:

`<module:Geos>': superclass mismatch for class CAPIPointImpl (TypeError) 

...

我覺得我的天真在試圖讓CAPIPointImpl(在這種情況下),以繼承另一個類比其父亮點關於這個問題我的知識差距非常明確

我可以使用什麼方法實際上將額外的共享方法嫁接到來自其他獨立父母的兩個類上? ruby是否允許這些類型的抽象異常?

+0

Ruby不支持多重繼承。如果您嘗試重新打開一個已經定義的具有繼承性但帶有不同父級的類,那麼您將得到您發佈的錯誤。去看看模塊,看看理查德庫克下面說什麼,你應該能夠得到你想要的。 – xaxxon

回答

4

您需要做的是在模塊中定義新方法,然後「混合」到現有類中。這裏有一個草圖:

# Existing definition of X 
class X 
    def test 
    puts 'X.test' 
    end 
end 

# Existing definition of Y 
class Y 
    def test 
    puts 'Y.test' 
    end 
end 

module Mixin 
    def foo 
    puts "#{self.class.name}.foo" 
    end 

    def bar 
    puts "#{self.class.name}.bar" 
    end 
end 

# Reopen X and include Mixin module 
class X 
    include Mixin 
end 

# Reopen Y and include Mixin module 
class Y 
    include Mixin 
end 

x = X.new 
x.test # => 'X.test' 
x.foo # => 'X.foo' 
x.bar # => 'X.bar' 

y = Y.new 
y.test # => 'Y.test' 
y.foo # => 'Y.foo' 
y.bar # => 'Y.bar' 

在這個例子中,我們有兩個已經存在的類XY。我們定義了我們想要添加到XY中的方法,該方法被稱爲Mixin。然後,我們可以重新打開XY,並將模塊Mixin包括在其中。完成後,XY都有其原始方法和Mixin中的方法。