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

Call subclass method from superclass - Design Pattern

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

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

它有效,但如果有更好的解决方案,我将不胜感激。与某些自定义 hack 不同,我想尽可能多地遵循最佳实践解决方案。

提前致谢!

这是一个很正常的模式。然后,您可以在每个 child class 中以不同方式实现 whatever,而不必在每个 update 中重新实现 update。我要补充的是:

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

Animalclass。这样,如果您从未实现 whatever 的 child class 调用 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)。
  • 我已经以更传统的方式定义了 class 方法(但 OP 定义它们的方式没有任何问题)。
  • update 只能从子classes 调用,因为Animal.update 会引发"there's no method or local variable 'whatever'" 异常。

这里的重点是 Tiger.update 调用了方法 Animal::update 就好像 update 已经在 Tiger[=47 中定义了一样=],而不是继承自 Animal。这就是为什么:

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

因此,"call a class method of a child class from a parent class"不正确; Tiger::whatever 正在从 child class 调用。 parent class 没有调用任何内容,因为在调用 Tiger::updateself 永远不会等于 Animals。这不仅仅是语义。