当我在一个孩子上调用一个实例方法但是孩子还没有定义它时,我想引发异常。鉴于代码:
class Parent
def foo
'hihi'
end
end
class Child < Parent
end
是否可以以引发此异常的其他方式调用Child.new.foo
?
我明白我可以
class Parent
def foo
unless self.class.instance_methods(false).include? :foo
raise Exception.new("Child didn't define foo!")
end
'hihi'
end
end
我想知道是否可以在没有这个的情况下执行此操作以及我实际执行Child.new.foo
调用的位置。
谢谢!
答案 0 :(得分:5)
您是否需要简单的Parent
个实例成功回复foo
?
如果您尝试制作抽象方法,只需在Parent#foo
中引发异常,并避免在任何子类“super
中调用foo
。
class Parent
def foo
raise "abstract Parent#foo"
end
end
class Child < Parent
# this will raise an exception
end
class OtherChild < Parent
# this won't raise an exception
def foo
'blah'
end
end
另一方面,您可以像这样使用方法检查
class Parent
def foo
if self.class.instance_method(:foo).owner == Parent
raise "abstract" unless self.instance_of? Parent
end
"fifi"
end
end
class Child < Parent
# this will raise an exception
end
class OtherChild < Parent
# this won't raise an exception
def foo
'blah'
super
end
end
这具有定义该方法的任何中间类将阻止该异常的属性。
如果你想强制每个子类来定义方法(不仅仅是有一些中间定义),你可以使用
if self.class.instance_method(:foo).owner != self.class
作为条件
答案 1 :(得分:1)
这是一种方法:在基类中实现inherited
(参见Ruby docs),并从那里定义要强制子类覆盖的方法:
class Parent
def self.inherited(child)
child.send(:define_method, :foo) do
raise "You must implement #{child}#foo!"
end
end
def foo
'hihi'
end
end
现在,任何继承自Parent
的类都将以引发异常的foo
方法开始。当您在派生类中显式实现foo
时,它将覆盖此默认实现。
我喜欢这种方法,它不应该为每次foo
的调用增加额外的开销。