拥有一个不同于私有的公共构造函数

时间:2016-12-14 22:49:03

标签: ruby constructor

我读到有一个类的几个构造函数是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被调用两次,这不是一件好事。

有没有办法给公共构造函数,而私有一个更完整的方法来创建一个新实例?如果没有,做类似事情的最佳方式是什么?

2 个答案:

答案 0 :(得分:1)

一种简单的方法是接受初始化选项,您可以在其中包含if语句,涵盖私有或公共案例。

Ruby并没有真正拥有“私人课程”的概念。以一种简单的方式,比如说'私人'。

您可以看到How to I make private class constants in Ruby获取私有常量的方法(因为类是常量)。您创建了一个返回匿名类(Class.new do ... end)的类方法。然后使用private_class_method将该类方法标记为私有。

更好的解决方案是使两个具有不同初始化的类。常用功能可以在单独的类或模块中。如果它是一个课程,那么将它们包含在公共/私人课程中的方式就是这样。类将是继承。如果它是一个模块,那么你是include/extend

答案 1 :(得分: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 gem

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
相关问题