Ruby继承和覆盖类方法

时间:2015-10-13 00:50:35

标签: ruby inheritance class-method

我已经设置了两个类,如下所示

class Parent

  def self.inherited(child)
    child.custom_class_method
  end

  def self.custom_class_method
    raise "You haven't implemented me yet!"
  end
end

class Child < Parent

  def self.custom_class_method
    "hello world"
  end
end

似乎在评估继承Child < Parent时,它会调用self.inherited,而Parent会提升self.custom_class_method的{​​{1}}版本,而不是Child }}的。这是一个问题,因为我没有收到预期的"hello world",而是提出错误,说"You haven't implemented me yet!"

Child的{​​{1}}完成评估之后,self.custom_class_method的{​​{1}}是否会被评估?如果是这样的话,或许可以解决这个问题?我应该不对父类进行Parent检查吗?

2 个答案:

答案 0 :(得分:3)

我认为这应该澄清:

class Parent
  def self.inherited(child)
    puts "Inherited"
  end
end

class Child < Parent
  puts "Starting to define methods"
  def self.stuff; end
end

输出清楚地表明,在您打开新课程时会调用.inherited,而不是在您关闭它时。因此,正如您所猜测的那样,Child.custom_class_method在您尝试调用时并不存在 - 所有.inherited看到的都是空白。

(关于如何解决这个问题......不幸的是,如果没有更深入地了解你想要做什么,我不能说。)

答案 1 :(得分:2)

模板模式/延迟初始化可能有助于解决您的问题。代码假定子类之间的不同之处是数据库连接信息,可能只是表名或可能是完全不同的数据库。父类具有创建和维护连接的所有代码,让孩子们只负责提供不同的东西。

class Parent
  def connection
    @connection ||= make_connection
  end

  def make_connection
    puts "code for making connection to database #{database_connection_info}"
    return :the_connection
  end

  def database_connection_info
    raise "subclass responsibility"
  end
end

class Child1 < Parent
  def database_connection_info
    {host: '1'}
  end
end

class Child2 < Parent
  def database_connection_info
    {host: '2'}
  end
end

child1 = Child1.new
child1.connection  # => makes the connection with host: 1
child1.connection  # => uses existing connection

Child2.new.connection  # => makes connection with host: 2