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

barkAnimalあなたが定義するメソッドは、今のところクラスレベルではなくメソッドとしてクラスに属して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次に、 inheritingfromと呼ばれるクラスを作成しますAnimal。ですので、そうでない限りbark利用できます。Cowoverridden

 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 に答える