2016-12-14 6 views
0

クラスのコンストラクタを複数持つには、not possibleだと読んでいます。私は静的メソッドでpublicコンストラクタを置き換えるについて考えているプライベートなものとは別のパブリックコンストラクタを持っている

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は良いことではありませんこれは、2回呼び出されます:私はまた、民間のポスト初期化メソッドを作ることについて考えてきました。

パブリックコンストラクタを提供する方法はありますか?プライベートで新しいインスタンスを作成する方法はありますか?そうでない場合は、何か類似のことをする最良の方法は何ですか?

+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は、「プライベート」と言ったような単純な方法で、この「プライベートクラス」の概念を実際に持っていません。

プライベート定数を作成するには、How to I make private class constants in Rubyがあります(クラスは定数なので)。匿名クラス(Class.new do ... end)を返すクラスメソッドを作成します。その後、そのクラスメソッドをprivateにマークします(private_class_method)。

より良い解決策は、異なる2つのクラスを初期化することです。共通の機能は、別のクラスまたはモジュールに存在する可能性があります。それがクラスの場合、それらを 'public/private'クラスに含める方法は継承になります。それがモジュールならば、あなたはinclude/extendでしょう。

+0

'クラスは定数なので'クラス名はクラスを指す定数ですが、クラス自体は定数です。 –

+0

最初の解は分かりません。返された匿名クラスはどのように役立つべきですか?メインクラスを継承していますか? 2番目の解決方法はより明確に見えますが、明白な理由で2つのクラスに対処しなければならないため、ユーザーにとって非常に悪いことです。それにもかかわらず、あなたはポイントを持っています。 – Codoscope

関連する問題