0

私は4つのクラス(Point、Shape、Rectangle、Circle)を持つプログラムを書いています。Rectangle と Circle は、形状の中心に関する情報 (フィールド) を含む Shape から継承します。次のように出力されるはずの Circle クラスの to_s メソッドを作成しようとしています。

サークル: [(1, 2), 3]

(1,2) が中心で、3 が半径です。これは私が to_s メソッドのために持っているものです:

def to_s
  "Circle: [(" + super.x.to_s + ", " + super.y.to_s + "), " + 
    radius.to_s + "]"
end

「No such method 'x' error」というエラーが表示されますが、これは Shape に 'x' メソッドがない (Point にある) ためだと理解しています。super.center.y.to_s のような長いメソッド チェーンを試してみましたが、それ自体に問題があります。これを行う正しい方法は何ですか。つまり、良いプログラミング スタイル、オブジェクト指向の方法、および Ruby の方法ですか?

4

2 に答える 2

4

を呼び出すsuperと、親クラスのto_sメソッドが送信され、その結果 (文字列) が送信さxyます。これらは、文字列には存在しないメソッドです。

これを試して:

def to_s
  "Circle: [(#{x},#{y}) #{radius}]"
end

Ruby には暗黙的な文字列補間があります。つまり、二重引用符で囲まれた文字列では、内部のすべて#{...}が自動的に文字列としてレンダリングされます。

またはで定義されてxいない場合、何から取得することを期待しますか? から継承しますか?xShapeCircleShapePoint

編集:

との値@centerを保持するインスタンス変数 にアクセスするには、いくつかのオプションがあります。これは最も基本的なものです:xy

class Shape
  attr_accessor :center

  def initialize(point)
    @center = point
  end
end

class Circle

  def initialize(point, radius)
    super(point) # this runs Shape's initialize method
    @radius = radius
  end

  def to_s
    "Circle: [(#{center.x},#{center.y}) #{radius}]"
  end
end

別のオプションは、組み込みの Forwardable モジュールを使用することです。

require 'forwardable'
class Shape
  extend Forwardable
  def_delegators :@center, :x, :y
  #...
end

次に、インスタンスでxand をy直接呼び出すことができ、それらは自動的に に転送されます@center。この場合、"Circle: [(#{x},#{y}) #{radius}]" 文字列が機能します。

于 2012-11-16T01:22:06.680 に答える
0

ルビーでは、スーパーは、スーパークラス自体ではなく、上書きされたメソッドを表すメソッドにすぎません。

例:

class A
    def to_s
        'A'
    end
end

p A.new.to_s #=> returns 'A'

class B < A
    def to_s
        super + 'with' + 'B'
    end
end

p B.new.to_s #=> returns 'A with B'

それが得られなかった場合は、呼び出しsuperのみを呼び出しA.to_sAそれ自体は呼び出しませんA。プロパティの呼び出しがあった場合、スーパークラス全体ではなく、呼び出された現在オーバーライドされているメソッドのみを表すため、x呼び出しsuper.xは失敗します。superこれで、スーパークラスのプロパティにアクセスするには、呼び出すだけで@x.to_sよいかself.x.to_s、スーパークラスのプロパティがサブクラスに属しているためです。

于 2012-11-16T01:46:58.980 に答える