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のオブジェクト指向へのアプローチにより、この構造が役立つ可能性のある目標を達成する他のパターンにアクセスできるという点で、ここで他の回答に同意すると思います(おそらく他の言語で)。私が関わってきたプロジェクトでは、この種のクラス/スーパークラスメソッドの変更は実際には見られません。

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