【问题标题】:Call subclass method from superclass - Design Pattern从超类调用子类方法 - 设计模式
【发布时间】:2015-04-18 08:23:03
【问题描述】:

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

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 不同,我想尽可能遵循最佳实践解决方案。

提前致谢!

【问题讨论】:

  • 您在Tiger 中的update 方法永远不会被调用。 Tiger的单例类继承了Animals的单例类中定义的方法。

标签: ruby oop inheritance


【解决方案1】:

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

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

Animal 类。这样,如果你从一个没有实现whatever 的子类调用ChildClass.update,你会得到一个有用的错误。

【讨论】:

  • 优秀。谢谢@ptd!
  • 除了将引发异常的类方法whatever 添加到Animals 之外,将Animals::update 的第一行设置为以下内容可能会很有用:raise NotImplementedError, "update is only to be called from subclasses" if self == Animals。也许让你的错误消息"class #{self} must implement..."
【解决方案2】:

试试这个:

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 会引发“没有方法或局部变量 'whatever'”异常。

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

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

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

【讨论】:

    猜你喜欢
    • 2011-10-24
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    相关资源
    最近更新 更多