从超类调用子类方法 - 设计模式
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
到Animal
class。这样,如果您从未实现 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::update
时 self
永远不会等于 Animals
。这不仅仅是语义。
我被困在这里,因为我担心从父 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
到Animal
class。这样,如果您从未实现 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::update
时 self
永远不会等于 Animals
。这不仅仅是语义。