从超类调用子类方法 - 设计模式

时间:2015-02-17 15:24:55

标签: ruby oop inheritance

我被困在这里,因为我担心从父类调用子类的类方法是否是最佳做法?

module Zoo

  class Animals
    class << self
      def update
        if self.whatever == ... # Calls method 'whatever' from Tiger class
          # do sth.
        end    
      end
    end
  end

  class Tiger < Animals      
    def update
      super
    end
    class << self
      def whatever
        "whatever from tiger class"
      end
    end
  end
end

Zoo::Tiger.update

它有效,但我希望能更好地解决这个问题。我希望尽可能地遵循最佳实践解决方案,这与一些自定义黑客不同。

提前致谢!

2 个答案:

答案 0 :(得分:3)

这是一种非常正常的模式。然后,您可以在每个子类中以不同方式实现whatever,而无需在每个子类中重新实现update。我要补充的是:

def self.whatever
  raise NotImplementedError, 'Class must implement whatever' # or some useful message
end

Animal课程。这样,如果您从未实现ChildClass.update的子类调用whatever,则会收到有用的错误。

答案 1 :(得分:1)

试试这个:

class Animals
  def self.update
    puts "self = #{self} in Animals::update"
    if whatever == "Happy Days"
      puts "The Fonz rules"
    end    
  end
end

class Tiger < Animals      
  def self.whatever
    "Happy Days"
  end
end

Tiger.update
  # self = Tiger in Animals::update
  # The Fonz rules

在讨论之前,请注意几点:

  • 我删除了模块Zoo和实例方法Tiger#update,因为它们与问题无关。
  • 我已从self.删除self.whatever,因为不需要self如果没有明确的接收方,则会假设update
  • 我以更传统的方式定义了类方法(但是OP定义它们的方式没有任何问题。)
  • Animal.update只能从子类调用,因为Tiger.update会引发“没有方法或局部变量'无论''异常。

这里重点是Animal::update调用方法update,就像在Tiger 中定义了Animal一样,而不是从Tiger.methods.include?(:update) #=> true 继承而来。这就是原因:

Tiger::whatever

因此,“从父类调用子类的类方法”是不正确的;正在从子类中调用self。从父类调用没有任何内容,因为Animals在调用Tiger::update时永远不会等于{{1}}。这不仅仅是语义。