こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

【ruby】【文法】スパークラスのスーパークラスのメソッドを呼び出したい

スパークラスのスーパークラスのメソッドを呼び出したいです。

たとえば、Hoge3のスーパークラスがHoge2で、さらにそのスーパークラス
がHogeの時、Hoge3からHogeのメソッドを呼び出したいのです。

もう少し具体的に説明させてもらいます。

class Hoge
 def initialize()
  @name='hoge'
 end
end

class Hoge2 < Hoge
 def initialize()
  super
  @name='hogehoge'
 end
end

class Hoge3 < Hoge2
 def initialize()
  super #これではスーパークラスHoge2のメソッドが呼ばれてしまう。
  puts @name 
end

Hoge3.new()

上記実行結果は、hogehogeが出力ですが、
スーパークラスのスーパークラスが設定した@name値、
'hoge'が出力されるようにしたいです。

『Hoge3クラスはHoge2クラスを継承すればよいではないか?』
とも思うでしょうが、Hoge2クラスには、Hogeには無い機能が多く拡張されてると考えてください。

ご指導のほど、宜しくお願いいたします。

投稿日時 - 2009-09-24 20:17:58

QNo.5315898

暇なときに回答ください

このQ&Aは役に立ちましたか?

10人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

そもそも、Hoge3でsuperを呼ぶのがダメというか呼び出す必要ないのでは。
Hogeと同じinitializeコードをコピー&ペーストするなり、
Hogeのインスタンスをコンポジットして、(必要があれば特異メソッドを定義して)Hogeから情報を引っ張り出してくるとか。

毒を食らわば皿まで。

投稿日時 - 2009-10-03 23:37:54

お礼

osamuyさん。ご意見ありがとうございました。

投稿日時 - 2009-10-05 14:15:59

ANo.3

#2です。

無理矢理やるとすると、
class Hoge
 def initialize()
  @name='hoge'
 end
end

class Hoge2 < Hoge
 def initialize()
  super
  unless self.class == Hoge3
   @name='hogehoge'
  end
 end
end

class Hoge3 < Hoge2
 def initialize()
  super #これではスーパークラスHoge2のメソッドが呼ばれてしまう。
  puts @name 
end

Hoge3.new()

投稿日時 - 2009-09-26 10:08:07

補足

notnotさん、たびたびのご回答ありがとうございます。

#2での補足に記したとおりでして、
Hoge2にはできれば、手を入れたくないのです。
説明不足ですみません。
Hoge2は#2での補足で言うところの、
class ZipOutputStream
に該当すので、

Hoge3でsuperした時にHoge2でsuperしたのと同じことをしたいのです。

投稿日時 - 2009-09-26 15:05:56

ANo.2

クラスの設計が間違っていると思いますが、どうすればいいのかはこれだけではなんとも。

>『Hoge3クラスはHoge2クラスを継承すればよいではないか?』
は、『Hoge3クラスはHogeクラスを継承すればよいではないか?』の間違いですよね。
Hoge2でいろいろメソッドが定義されているということなら、moduleにしてincludeすればいいのでは?

投稿日時 - 2009-09-26 00:03:22

補足

notnotさん、ご回答ありがとうございます。

たびたびのご回答で、感謝しております。

>は、『Hoge3クラスはHogeクラスを継承すればよいではないか?』の間違いですよね。
すみません。誤記です。

実はこの質問、notnotさんに先日ご回答頂いた質問
http://oshiete1.goo.ne.jp/qa5307792.html
から派生しております。

すごく具体的にやりたい事を書きに記します。

module Zip
 class ZipOutputStream
  include IOExtras::AbstractOutputStream

  ・・ snip ・・

  def initialize(fileName)
    super()
    @fileName = fileName
    @outputStream = File.new(@fileName, "wb")

    ・・ snip ・・

元のソースが上記になってまして、これを以下の様にクラス継承すると
した場合でして。。

require 'zip/zip'
module ZipKai
 include Zip

 class ZipOutputStreamKai < ZipOutputStream
  def initialize()
   super() #※←ここ。スーパークラスのZipOutputStreamでsuperするのと同じ意味合いにしたい
   @outputStream = IO.new(1, "wb") #これでは上手くいかないのは別件

  ・・ snip ・・

アドバイスの程、宜しくお願いいたします。

投稿日時 - 2009-09-26 02:15:14

ANo.1

hoge2がhogeを継承する際に、aliasで別名の定義をしておいて、Hoge3ではその別名を呼べば良いのではないでしょうか。

class Hoge
 def initialize()
  @name='hoge'
 end
end

class Hoge2 < Hoge
 alias :hoge_initialize :initialize
 def initialize()
  super
  @name='hogehoge'
 end
end

class Hoge3 < Hoge2
 def initialize()
  hoge_initialize
  #super #これではスーパークラスHoge2のメソッドが呼ばれてしまう。
  puts @name
 end
end

Hoge3.new()

投稿日時 - 2009-09-25 20:02:48

補足

siffon9さん、ご回答ありがとうございます。

できれば、Hoge2には手を入れてくありません。
実はHoge2は、第三者提供のライブラリなもので。
説明不足ですみませんでした。

でも、アドバイスありがとうございました。

投稿日時 - 2009-09-26 15:01:42

あなたにオススメの質問