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



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

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

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

提前感谢!

这是一个

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

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

Animal类。这样,如果您从未实现whatever的子类调用ChildClass.update,则会出现一个有用的错误。

试试这个:

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.whatever中删除了self.,因为它不是必需的(如果没有明确的接收器,则假设self(。
  • 我以更传统的方式定义了类方法(但 OP 定义它们的方式没有错(。
  • update只能从子类调用,因为Animal.update会引发"没有方法或局部变量'随便'"异常。

这里重要的一点是Tiger.update调用方法Animal::update就好像update是在Tiger中定义的,而不是从Animal继承的。这就是为什么:

Tiger.methods.include?(:update) #=> true

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

最新更新