0

当我对孩子调用实例方法但孩子尚未定义它时,我想引发异常。给定代码:

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呼叫。

谢谢!

4

2 回答 2

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

作为条件

于 2013-06-27T15:29:37.957 回答
1

这是一种方法:在基类中实现inherited(请参阅Ruby 文档),然后从那里定义要强制子类覆盖的方法:

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.

于 2013-06-27T16:27:10.237 回答