我被困在这里,因为我担心从父类调用子类的类方法是否是最佳做法?
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
它有效,但我希望能更好地解决这个问题。我希望尽可能地遵循最佳实践解决方案,这与一些自定义黑客不同。
提前致谢!
答案 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
。Animal.update
只能从子类调用,因为Tiger.update
会引发“没有方法或局部变量'无论''异常。这里重点是Animal::update
调用方法update
,,就像在Tiger
中定义了Animal
一样,而不是从Tiger.methods.include?(:update) #=> true
继承而来。这就是原因:
Tiger::whatever
因此,“从父类调用子类的类方法”是不正确的;正在从子类中调用self
。从父类调用没有任何内容,因为Animals
在调用Tiger::update
时永远不会等于{{1}}。这不仅仅是语义。