2016-12-14 50 views
0

我讀到它是not possible有一個類的幾個構造函數。所以,下面的代碼將無法正常工作:有一個不同的公共構造函數,而不是私有的構造函數

class C 
    def initialize x 
     initialize x,0 
    end 

    # Some methods using the private constructor… 

    def foo 
     # … 
     bar = C.new 3,4 
     # … 
    end 

    private 

    def initialize x,y 
     @x = x 
     @y = y 
    end 
end 

我曾經想過用一個靜態方法代替公共構造函數,但是這將防止其他類來擴展C。我也考慮過使用私有後期初始化方法:

class C 
    def initialize x 
     post_init x,0 
    end 

    # Some methods using the private constructor… 

    def foo 
     # … 
     bar = C.new baz 
     bar.post_init 3,4 
     # … 
    end 

    private 

    def post_init x,y 
     @x = x 
     @y = y 
    end 
end 

但是在這裏,post_init被調用兩次,這不是一件好事。

有沒有辦法給一個公共的構造函數,而私下有一個更完整的方法來創建一個新的實例?如果不是,做類似的最好方法是什麼?

+0

我真的不明白你爲什麼想要這樣做,但是你想出什麼似乎符合你的目的,除了你的代碼中的'post_init'是一個類方法,但是你從實例方法調用它,這是行不通的。 –

+0

我對類方法犯了一個錯誤,它應該是一個實例方法。因此我更新了這個帖子。 – Codoscope

+0

你有沒有想過直接改變'@ y',你需要什麼?它看起來像一個更常見和直接的方法 –

回答

1

我想這會做你的期望。

class C 
    def initialize(x, y = 0) 
    @x = x 
    @y = y 
    end 

    def self.with_position 
    new(3, 4) 
    end 
end 

c1 = C.new(5) 
c2 = C.with_position 

如果要禁止從類之外的任何人設定y,您可以在後臺使用一些私有方法(如你所說)和konstructor寶石

class C 
    def initialize(x) 
    set_coords(x, 0) 
    end 

    konstructor 
    def with_position 
    set_coords(3, 4) 
    end 

    private 

    def set_coords(x, y) 
    @x = x 
    @y = y 
    end 
end 

c1 = C.new(5) 
c2 = C.with_position 
+0

「konstructor」'with_position'可以在'private'下嗎? – Codoscope

+0

是的,它可以在'私人' – snovity

+0

你可以閱讀詳細的Ruby構造函數如何工作在這裏https://github.com/snovity/konstructor#details – snovity

1

一個簡單的方法是接受初始化選項,您可以在那裏有一個if聲明,涵蓋私人或公共案例。

Ruby並沒有像'private'這樣簡單的方式真正擁有'private class'這個概念。

你可以看到How to I make private class constants in Ruby的方法來使一個私人常量(因爲類是常量)。您將創建一個返回匿名類的類方法(Class.new do ... end)。然後用private_class_method將該類方法標記爲private。

更好的解決方案是使兩個不同的初始化類。通用功能可以在單獨的類或模塊中。如果它是一個類,那麼將它們包含在「公共/私有」類中的方式就是繼承。如果它是一個模塊,那麼你會include/extend

+0

'因爲類是常量'我認爲類的名字是一個常量指向一個類,但類本身是一個常數:) –

+0

我不明白第一個解決方案。返回的匿名類應該如何有用?它是否繼承了主類?第二種解決方案似乎更清楚,但對用戶來說非常糟糕,因爲他不得不面對兩個類別,原因不明。儘管如此,你還是有一個點。 – Codoscope

相關問題