覆盖模块的方法是一个好的约定吗?

Is overriding a module's method a good convention?

我有某种 template patterned 模块,其中定义的方法很少(默认行为),有些看起来像下面的方法:

def tax
  1.2
end

def do_something!
  raise "Please implement it in your class"
end

我读到在大多数情况下我应该使用模块而不是继承,因为继承能力(单一继承)以及当我根本不需要 super() 时。

但是我觉得覆盖所有 raise "..." 方法和一些默认方法(比如 tax 方法)有点内疚,因为它是模块。

你怎么看?

当我需要覆盖方法时,我应该使用继承还是包含模块?

我通常遵循的规则是:当必须在 class 中定义方法时,包括模块(例如,模块充当接口)我总是这样做:

def method_that_needs_to_be_defined
  raise NoMethodError
end

这是一个很好的做法,可以防止意外调用尚未定义的方法。

示例:

module Speaker
  def speak
    raise NoMethodError
  end
end

class Bird < Animal
  include Speaker

  def speak
    'chirp'
  end
end