5

これはどのように機能しますか?

class A
  attr_accessor :name

  def initialize params
    @name = params[:name]
    @collection << B.new 
  end
end

class B < A
  def initialize
    @my_name = lookup_something(<parent.name>)
  end
end

基本的に、子クラスのルックアップで使用するには親クラスの値が必要ですが、より良い方法がある場合は、明示的に渡したくありません。親のインスタンス変数は、子クラスでは完全にアクセスできませんか?それとも、これは単に貧弱な階層設計ですか?

4

3 に答える 3

8

ここで何をしようとしているのかよくわかりません。投稿したすべてのコードはインスタンス変数で機能します。インスタンス変数はクラスごとではなくオブジェクトごとであるため、「親クラスの値が必要です」と言ったときの意味がわかりません。

私があなたのコードで注意することがいくつかあります:

  • 基本クラスはサブクラスを認識してはなりません。したがって、ベースがサブクラスを使用するため、でBオブジェクトを作成することは適切ではありません。A#initialize
  • B#initializeとはまったく異なる動作でクラスを上書きしていますA#initializeパラメータリストを変更することもできます。あまり良いことでもありません。サブクラスのオブジェクトは、そのスーパークラスのオブジェクトと同じように動作する必要があります。
  • メソッドが呼び出されることはないため、呼び出すときB.new('myname')に変数@nameが割り当てられることA#initializeはありません。super(:name => name)(スーパークラスを実行するために)を呼び出すか、で直接initialize割り当てる必要があります@nameB#initialize
  • 定義すると@name、すべてのインスタンスメソッドがその値を使用できるようになります。親/スーパークラスで定義されているものを含みます。

なぜここで継承を使用しているのかよくわかりませんが、それはあなたが望んでいるものではないと感じています。2つの異なるものに対して2つのクラスがある場合、継承が関係することはありません。コードを再利用する場合は、Rubyのミックスイン機能を確認するか、再利用したい動作を持ついくつかの「小さい」オブジェクトで複雑なオブジェクトを作成します。

于 2010-05-20T15:30:45.937 に答える
3

John Nunemakerは、このトピックに関する素晴らしい記事を掲載しています。

于 2010-05-21T22:09:49.860 に答える
2

B継承したい理由は何Aですか?別の理由がない限り、これを設計する正しい方法は、名前をBコンストラクターのパラメーターとして使用し、継承を破棄することです。

class A
  attr_accessor :name

  def initialize params
    @name = params[:name]
    @collection << B.new(@name)
  end
end

class B
  def initialize name
    @my_name = lookup_something(@name)
  end
end
于 2010-05-20T14:41:51.560 に答える