Ruby - 类方法中的引用子类

时间:2015-10-26 23:49:15

标签: ruby class inheritance

不确定Ruby是否可以实现这一点,但我正在尝试编写一个具有多个方法的类,这些方法将由许多子类共享。这个超类将包含我希望子类继承的类和实例方法。假设我永远不会直接使用超类,我只是用它来抽象出重复的方法(思考DRY)。这涉及使常量(API URI)从子类变为子类。

这是我想要做的一个例子:

class Foo
  attr_accessor :param
  def initialize(param)
    @param = param
  end
  def self.get
    <SubClass>.new(self::MY_CONSTANT)
  end
end

class Bar < Foo
  MY_CONSTANT = 'Woot'
end

class Baz < Foo
  MY_CONSTANT = 'Pew Pew'
end

我想要的行为是这样的:

Bar.get
puts Bar.param # => Woot
Baz.get
puts baz.param # => Pew Pew

这可能吗?我完全以错误的方式接近这个吗?

更新

Per @Nathan,self.new方法中的self.get在这里做了诀窍。

[39] pry(main)> test = Bar.get
=> #<Bar:0x000001072ecc20 @param="Woot">
[40] pry(main)> test.param
=> "Woot"
[41] pry(main)> test
=> #<Bar:0x000001072ecc20 @param="Woot">
[42] pry(main)> test.class
=> Bar
[43] pry(main)> test2 = Baz.get
=> #<Baz:0x000001071b5528 @param="Pew Pew">
[44] pry(main)> test2.class
=> Baz
[45] pry(main)> test2.param
=> "Pew Pew"

1 个答案:

答案 0 :(得分:3)

使用self

Foo.get内,self是您正在调用get的类,当您执行Bar时,它将是BazBar.get分别和Baz.get

因此,如果你有<SubClass>,只需放self,一切都会按预期运作。

def self.get
  self.new(self::MY_CONSTANT)
end

您也可以省略self,因为这是Ruby在未指定显式对象时自动使用的内容。

def self.get
  new(self::MY_CONSTANT)
end

此外,在您测试值的代码中,我认为您想要的是:

bar = Bar.get
puts bar.param # => Woot
baz = Baz.get
puts baz.param # => Pew Pew

最后,至于这是否是最好的方式,这是基于意见的,但对我来说似乎很奇怪,当它已经作为常量可用时,你试图将值传递给initialize。换句话说,如果您有一个需要使用API​​ URI的方法,只需直接引用常量,而不是使用@param初始化实例本身。您可以在实例方法中引用常量,如下所示:self.class::MY_CONSTANT