2016-12-14 49 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

相关问题