2

我正在使用 Ruby,并使用继承编写类。

例如:

class Canine
  def initialize
  end

  def make_noise
    puts "whoosh whoosh"
  end
end

class Dog < Canine
  def initialize
  end

  def make_noise
    puts "wong wong"
    super
  end
end

现在我有一个狗对象:

jack = Dog.new

是否可以make_noise()通过对象调用Canine的方法dog

在其他语言中,这将是一种类型转换,例如:

(Canine)jack.make_noise

请注意,这不是 Ruby 语法,因此是我的问题。

在 Ruby 中可以做到这一点吗?如果是这样,怎么办?

4

4 回答 4

4

你可以这样做:

Canine.instance_method(:make_noise).bind(jack).call

更好的计划是只给超类中的方法一个别名,或者重命名它。

于 2013-04-26T15:22:24.697 回答
3

Ruby 不允许以这种方式进行转换或转换,至少在传统意义上是不允许的。无论如何,这很少需要,因为 Ruby 是基于鸭子类型而不是严格的类型系统。

您是否期待通话中的“嗖嗖嗖嗖”?只有在 C++ 等更严格类型的语言中,非虚拟方法才会发生这种情况。它违背了正确的面向对象设计。

如果你探索面向对象设计中使用的设计模式,你总是可以用另一种方式解决这类问题。

您可能想要的是一个演示者来处理该make_noise功能。

否则,您将需要编写一个to_canine可以转换为基本类型的方法,尽管仍然不清楚您为什么需要这样的东西。

于 2013-04-26T15:21:41.897 回答
3

你可以这样做:

d = Dog.new
d.class.superclass.instance_method(:make_noise).bind(d).call

或者

Canine.instance_method(:make_noise).bind(d).call

. . . 不漂亮!我不确定是否有更好的方法

编辑:我想我同意这里的其他答案,因为 Ruby 的 OO 方法将使您能够访问其他模式,这些模式可以实现该构造可能帮助您实现的任何目标(也许在其他语言中)。在我参与的项目中,我没有看到这种类/超类方法在实践中发挥作用。

于 2013-04-26T15:22:23.533 回答
0

我不知道你为什么需要这个,根据需要它可能会完全不同,但在知识有限的情况下我会建议这个

class Dog < Canine
  def initialize
  end

  def make_noise only_parent=false
    puts "wong wong" if !only_parent
    super
  end
end

或者

class Dog < Canine
  def initialize
  end

  alias :make_super_noise :make_noise

  def make_noise
    puts "whoosh whoosh"
    super
  end
end
于 2013-04-26T21:05:11.703 回答