在Ruby中,是否可以从超类方法中获取子类方法而不影响子类中的代码?我试图避免在子类中调用super
。
class SuperClass
def do_something
puts "getting ready..."
# how to then yield back to the subclass do_something method?
puts "done."
end
end
class SubClass < SuperClass
def do_something
# how to first execute the superclass do_something method?
puts "doing something ..."
end
end
所需功能是专门致电SubClass.do_something
并收到以下输出:
“准备好......”
“做某事......”
“来完成。”
编辑:
也许真正的问题是:如何干掉下面的代码,从所有子类中删除对self.get_ready
和self.finish_up
的调用,使用任何保留这些类的ruby元编程技术DRY:< / p>
class SuperClass
def self.get_ready
puts "getting ready ..."
end
def self.finish_up
puts "done."
end
end
class SubClassA < SuperClass
def self.do_something
self.get_ready
puts "doing something ..."
self.finish_up
end
end
class SubClassB < SuperClass
def self.do_something
self.get_ready
puts "doing something else, a little differently..."
self.finish_up
end
end
class SubClassC < SuperClass
def self.do_something
self.get_ready
puts "doing something crazy..."
self.finish_up
end
end
答案 0 :(得分:4)
如果你真的不愿意使用super
,这几乎是不可能的。
使用super
,非常简单:
class SuperClass
def do_something
puts "getting ready..."
yield
puts "done."
end
end
class SubClass < SuperClass
def do_something
super.do_something do
puts "doing something..."
end
end
end
另一方面,如果您对多种方法持开放态度,则不使用super
,这会变得更简单:
class SuperClass
def do_something
puts "getting ready..."
self.actually_do_the_thing
puts "done."
end
def actually_do_the_thing
raise NotImplementedError
end
end
class SubClass < SuperClass
def actually_do_the_thing
puts "doing something..."
end
end
答案 1 :(得分:4)
在Practical Object-Oriented Design in Ruby中,Sandi Metz建议您克服呼叫超级的方法是定义一个&#34; hook&#34;超类中的方法,只有作业才会被子方法覆盖。在你的情况下,你可以做这样的事情:
class SuperClass
def self.do_something
puts "getting ready..."
do_something_child
puts "done."
end
def self.do_something_child; end
end
class SubClass < SuperClass
def self.do_something_child
puts "doing something ..."
end
end
SubClass.do_something