1

我只是想看看来自子类的实例方法调用,并使用了下面的测试代码:

class Animal
  def bark
    p "hukkhh"
  end
end
#=> nil

class Cow < Animal
end
#=> nil

Cow.public_instance_method(:bark)
#=> #<UnboundMethod: Cow(Animal)#bark>

class Cow
  bark
end
#=> NameError: undefined local variable or method `bark' for Cow:Class
#        from (irb):11:in `<class:Cow>'
#        from (irb):10
#        from C:/Ruby193/bin/irb:12:in `<main>'

从该代码中,我确认没有相应类的对象实例就无法执行实例方法。

但后来我尝试了下面的代码:

def talk
  p "hi"
end
#=> nil

Object.public_instance_method(:talk)
#=> #<UnboundMethod: Object#talk>

class Foo
  talk
end
# prints: hi
#=> "hi"

这里的输出让我对我的第一个测试代码输出感到困惑。

谁能帮我理解以上这些背后的事实?

4

1 回答 1

2

您定义的方法talk属于Object所有对象的根。因此talk方法适用于 ruby​​ 中的所有对象。

def talk
  p "hi"
end

Object.respond_to? :talk  #=> true

现在,您定义了类Foo,它也是一个 ruby​​ 对象。

Foo.is_a? Object  #=> true
Foo.respond_to? :talk  #=> ture

所以talk可以Foo上课。

现在你Animal用方法定义一个类bark

class Animal
  def bark
    p "hukkhh"
  end
end

bark您定义的方法现在属于Animal类,因为instance level方法不是类级别。这意味着您需要创建类的实例Animal来调用bark.

 Animal.respond_to? :bark  #=> false
 Object.respond_to? :bark  #=> false

 Animal.new.respond_to? :bark  #=> true
 Animal.respond_to? :talk   #=> true   #talk is available to Animal also because Animal is also object of Class
 Animal.new.respond_to? :talk  #=> true

现在您创建了一个名为Cow继承自的类Animal。所以bark是可用的,Cow除非它是overridden

 class Cow < Animal
 end

 Cow.respond_to? :bark  #=> false
 Cow.new.respond_to? :bark  #=> true
 Cow.respond_to? :talk  #=> true
 Cow.new.respond_to? :talk  #=> true

 Cow.new.bark #=> "hukkhh"  

所以要调用bark你需要创建类的实例。

如果您想调用在子使用中被覆盖的父方法super

class Cow < Animal
  def bark
    super
    #do your stuff
  end
end

Cow.new.bark  #=> "hukkhh"
于 2013-03-02T18:17:31.317 回答