• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:インスタンスとオブジェクト)

インスタンスとオブジェクトについての違いと理解方法

siffon9の回答

  • ベストアンサー
  • siffon9
  • ベストアンサー率64% (136/211)
回答No.2

こんにちは これは実際にクラスを定義して説明しないと分かりにくいのかなと思います。 なので簡単なプログラムを書いてみました。 (段付けに全角のスペースを使用しているので実行させる場合は半角スペースに書き換えが必要です) 後半の# => の右に書いてあるのがプログラムを実行したときに表示される文字です。 ------------------------------- class Person  def set_name(name)   @name = name   puts "Set @name : #{@name}"  end  def print_name   puts "My name is #{@name}"  end  def set_age(age)   var = age   puts "Set age : #{var}"  end  def set_height(height)   var = height   puts "Set height : #{var}"  end end taro = Person.new taro.set_name("Taro") # => Set @name : Taro taro.print_name # => My name is Taro taro.set_age(20) # => Set age : 20 taro.set_height(170) # => Set height : 170 jiro = Person.new jiro.set_name("Jiro") # => Set @name : Jiro jiro.print_name # => My name is Taro ------------------------------- 前半でPersonというクラスを定義しています。このクラスでは4個のメソッドと、@nameというインスタンス変数、下の二つのメソッドではvarというローカル変数を使用しています。 このクラスの定義が、言い換えれば設計図になります。 例えば一つの自動車の設計図から実体としての自動車がいくつも製造できるように、クラスの定義からも実体をいくつも作ることができて、この実体をインスタンスと言います。では、実体としてのインスタンスが何処にできるかというとコンピュータのメモリ空間の中に作られるのですね。具体的にどうなっているかは、今のところはあまり気にする必要はありません。 ではクラスの定義(設計図)からどうやってインスタンス(実体)を作るのかというと、それが次のプログラム行になります。 taro = Person.new jiro = Person.new ここではtaroとjiroという二つのインスタンス(実体)を作っています。インスタンスの中にはクラスの定義のとおりに@nameというインスタンス変数が存在して、4個のメソッドが使用可能になります。また、taroとjiroはそれぞれ個別の実体になります。ですからそれぞれの中に存在するインスタンス変数@nameもそれぞれ別のものとなります。 ここで、taroというインスタンスをみましょう。 taro.set_name("Taro") # => Set @name : Taro taro.print_name # => My name is Taro taroインスタンスのset_nameメソッドを利用して、インスタンス変数@nameに"Taro"という値をセットしていますね。次にtaroインスタンスのprint_nameというメソッドを利用して@nameの値を読み出して表示しています。同じインスタンス内のあるメソッドで設定したインスタンス変数の値が、同じインスタンス内の別のメソッドで読むことができるということですよね。つまりインスタンス変数はインスタンスの中にメソッドとは関係なく存在して値が保持されるということです。これが「同じインスタンス内であればメソッド定義を越えてその値を保持したままでいられる」という意味です。 つぎにローカル変数についてですが、 ローカル変数というのはメソッドの実行開始時に、コンピュータのメモリ空間のどこかに生成されてメソッドに実行が終わると破棄されて存在しなくなってしまいます。 taro.set_age(20) # => Set age : 20 taro.set_height(170) # => Set height : 170 このプログラム行では各の行で、taroインスタンスのset_ageメソッドとset_heghtメソッドが実行して、それぞれのメソッドでvarというローカル変数が使用されています。 set_ageメソッド開始時に作られたvarというローカル変数はset_ageメソッド終了時に破棄されます。そしてset_heghtメソッド実行時にまた別に作られます。つまりset_ageメソッドで使用したローカル変数varとset_hetghtメソッドで使用されたローカル変数は同じ名前ですが、まったくの別物ということですね。 ですからインスタンス変数の様に、あるメソッドでセットした値を別のメソッドで読み取るということは当然できません。これが「ローカル変数がメソッドごとに異なる」の意味です。 > hello = "Hello, Ruby." > p hello > puts hello > print hello > > どのメソッドでもローカル変数が持つ値は > 変わらないと思っていたのですが。 この4行のhelloというローカル変数が、ひとまとめで見えない一つのメソッドの中に書かれていると考えてみて下さい。 def 見えないメソッド  hello = "Hello, Ruby."  p hello  puts hello  print hello end 見えないメソッド開始時にhelloというローカル変数が作られて、見えないメソッド終了時にhelloというローカル変数は破棄されます。その間ではhelloは一つの変数として値を保持したまま存在します。 私も詳しく理解しているわけではありませんので、アバウトな説明になってしまいましたが、ご理解の一助にしていただければ幸いです。

noname#197548
質問者

お礼

回答ありがとうございます! 例え話はとても分かりやすいですね。 イメージではそれほど難しくなかったので、 言葉に表すととても長くなってしまい、 大変な思いをさせました。 本では、インスタンス変数を使うには 初期化しないと nil が返されると書かれています。 initialize メソッドで初期化するために あなたが書いてくれたコードを 少し書き換えて実行してみたのですが、 ArgumentError となってしまいます。 また少し調べてみます。 ありがとうございました。

関連するQ&A

  • インスタンス変数とローカル変数のスコープの違い

    Ruby言語を独学で勉強している者です。 現在たのしいRuby第3版という著書を参考にして勉強しています。 現在はクラスの継承、クラス文の定義の仕方を学んでいます。 そこで教えて欲しいのですが、 ローカル変数とはメソッドごとに異なる変数として扱われる。 インスタンス変数は同じインスタンスの中であればメソッドの定義を越えて その値を参照したり変更したりできるとあります。 そもそもインスタンスとは、オブジェクトとおほ同意義と捉えてるのですが この認識に間違いはないでしょうか。 ニュアンス的なものは理解したのですが、もう少しこの二つの変数の定義について 理屈を把握したいので、お手すきなお方がいらっしゃいましたら、具体的な例をあげて ご説明くださいませんか・・・。 この本すごく素人にもわかりやすい丁寧な解説で書いてあって、決して説明不足とは 思わないのですが、プログラマーさんの意見なども参考にしたくて投稿してみました。

    • ベストアンサー
    • Ruby
  • インスタンス変数とクラス変数の違い

    1つのクラスオブジェクト内のインスタンス全てで共有できる クラス変数 @@a と、 同じインスタンス内であればメソッドの定義を越えてその値を 参照したり、変更したりできるインスタンス変数 @a のスコープの違いをお手すきでしたらご指導願えませんか? あとクラス変数にはセッターやゲッター等のアクセスメソッドを 設定できるんですか? いろいろ知りたいです。

    • ベストアンサー
    • Ruby
  • Java 静的メソッドとインスタンスメソッド

    静的メソッドとインスタンスメソッドの使い分けがよくわかりません。 私の認識は 静的メソッド:インスタンスメンバ変数を参照する必要がない処理 インスタンスメソッド:インスタンスメンバ変数を参照して行う処理 と思っています。 よって、例えばDAOを作成する場合、select、update、insertを実行するメソッドを作成しますが、これらはクラスのインスタンスメンバ変数を参照する必要がないので静的メソッドにするべきだと思っています。 しかし、本やネットのDAOのサンプルプログラムはインスタンスメソッドで作成されています。 これらは、private static String の変数(SQL文が記述されている)を参照していますが、インスタンスメンバ変数は参照していません。 なぜselect、update、insertのメソッドをインスタンスメソッドにする必要があるのかわかりません。 静的メソッドとインスタンスメソッドの使い分けの基準を教えていただけないでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Java
  • クラス、オブジェクト、インスタンス、メソッドについて。

    クラス、オブジェクト、インスタンス、メソッドに ついて教えていただけないでしょうか? 今現在の自分の認識では、乗り物を例にすると、 「乗り物」という大枠がクラス。それを、たとえば 飛行機なり電車なり船なり、より具体的にした ものがインスタンス=オブジェクト。 その具体化したものの挙動、動作(走るとか飛ぶとか) がメソッド、という理解です。 ただ、これだとオブジェクトとインスタンスを 同じものとして見てしまっているので、この2つの 違いを明確に説明しろと言われると困ってしまいます。 インスタンスとオブジェクトの違いを明確にした上で うまく伝えられる方法があれば、ご教授ください。

  • 子クラスのインスタンスから親クラスのインスタンス変数の内容を表示する親クラスのメソッドを叩きたい

    お世話になっております。 rubyのコーディングで疑問が発生しましたので、質問させてください。 以下の様にクラスを定義してあるとします クラスA 体裁を整えて標準出力するクラス  ・インスタンス変数@Aを持つ  ・@Aを元に整形して標準出力する振る舞いを持つ クラスB Aの子クラスで、標準出力する内容を細かく設定するクラス  ・独自のインスタンス変数は持たない  ・親クラスのインスタンス変数@Aを編集する振る舞いを持つ 上記の実装である時、クラスBの振る舞いでクラスAのインスタンス変数@Aを編集しようとした際にエラーが発生します。 尚、レシーバはsuperです。 エラー内容 ./clsb.rb:49:in `edt_dsp': super: no superclass method `edt_dsp' (NoMethodE rror) エラー文中に出てる'edt_dsp'というメソッドが親クラスのインスタンス変数を編集するメソッドです。 尚、子クラスには独自の変数は無いのでinitializeメソッドは定義していません。 なぜこのようなエラーが発生してしまうのかわからず困っています。 現在自分でも色々とサイトを回って調べていますが、解決には至っていません。 ご回答いただければ幸いです。 以上です。よろしくお願いします。

    • ベストアンサー
    • Ruby
  • 戻り値で返したオブジェクトの寿命について

    Ruby初心者です。 【前置き】 メソッドで宣言した変数(以下arr)に値(以下[1,2,3])を代入し戻り値として返した場合、 メソッドの戻り値(以下retArr)には、[1,2,3]への参照(arr.object_id)が設定されると認識しております。 ----------------------- def method arr = [1,2,3] return arr end retArr = method() ----------------------- 【質問】 C言語の場合、関数内で宣言したローカル変数のアドレスを戻り値として返却した場合、 関数を抜けた時点で、そのアドレスの内容は保障されなくなりますが、 1.Rubyではその様な問題がなく動作するのは、何故でしょうか? 2.また、メソッド内で宣言したオブジェクト(上記[1,2,3])の寿命はいつまでなのでしょうか? 【備考】 いろいろと調べてみたのですが、オブジェクトの参照(object_id)は、ポインタに近い概念であることは記載されているのですが、その仕組みを理解できずに悩んでします。

    • ベストアンサー
    • Ruby
  • クラス変数/メソッドとインスタンス変数/メソッドの見え方について

    Javaの言語仕様(?)についてお教え下さい。 参照変数の型がインスタンスのスーパークラスの型の時、クラス変数/メソッドとインスタンス変数/メソッドの見え方が納得いかずに困っています。 以下のような条件の時です。   ・クラスが2つあり、1つはもう1つのクラスを継承しています。     それぞれを「スーパー」「サブ」と以下で呼びます。   ・インスタンスは"サブ"の型です。   ・上記インスタンスへの参照変数は"スーパー"のクラスの型です。   ・"スーパー"、"サブ"ともに【同名】の「クラス」変数/メソッド、「インスタンス」変数/メソッドがあります。 この場合に、"サブ"のインスタンスを参照している"スーパー"の型の変数を介し、それらにアクセスしたらどれが見えるか?という疑問です。 実験結果では以下のようになりました。           [フィールド]  [メソッド]   [1.static ]  スーパーの   スーパーの   [2.非static]  スーパーの   サブの 納得いかないのは「2.非static」で「フィールド」が、「スーパーの」になるところです。 これも「サブの」になると思っていました。 なぜサブクラスのが見えないのでしょうか? 同名の変数なのでスーパークラスのはサブクラスので隠れされ、サブクラスのが見えると思っていたのですが。 参考書には以下のように書いてありました。   フィールドの場合、参照変数の型のものが見える。   メソッドの場合、インスタンスの型のものが見える。 私には不自然に感じられるのですが、「こういう仕様だから。」と納得するしか無いのでしょうか? 「なぜこうなるか」について説明がある文献、サイトなどありましたらお教えください。 参考までに以下が実験したサンプルコードと結果です。長くて申し訳ありません。 「サンプルコード」 public class Super { static int staticField = 10; int instanceField = 100; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class Sub extends Super { static int staticField = 90; int instanceField = 900; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class TestStatic { public static void main(String[] args) { // インスタンスはSub、参照変数もSub、という状態。 Sub sub = new Sub(); System.out.println( "実験1" ); System.out.println( "1.クラス変数      " + sub.staticField ); System.out.print( "2.クラスメソッド    " ); sub.staticMethod(); System.out.println( "3.インスタンス変数   " + sub.instanceField ); System.out.print( "4.インスタンスメソッド " ); sub.instanceMethod(); // インスタンスはSub、参照変数はSuper、という状態。 Super sup = new Sub(); System.out.println( "実験2" ); System.out.println( "5.クラス変数      " + sup.staticField ); System.out.print( "6.クラスメソッド    " ); sup.staticMethod(); System.out.println( "7.インスタンス変数   " + sup.instanceField ); System.out.print( "8.インスタンスメソッド " ); sup.instanceMethod(); } } 「結果」 実験1 1.クラス変数      90 2.クラスメソッド    staticField = 90 3.インスタンス変数   900 4.インスタンスメソッド instanceField = 900 実験2 5.クラス変数      10 6.クラスメソッド    staticField = 10 7.インスタンス変数   100 8.インスタンスメソッド instanceField = 900 納得が行かないのは7のところです。 以上よろしくお願いいたします。

    • ベストアンサー
    • Java
  • ローカル変数の使いかた

    非常に初歩的なのですがrubyにおいてインスタンス変数、ローカル変数とクラス変数の使い分けがわかりません。 あるクラス内においてクラスから作られたすべてのオブジェクトに適用したい値はクラス変数に、インスタンスごとに違うのならインスタンス変数にするのはわかるのですが、クラス内でローカル変数はなぜ使うのでしょうか?受け取った引数もオブジェクトならインスタンス変数に、クラスならクラス変数に原理的には属すと思うのです。 あるオブジェクトがあるメゾッドを実行した時にそのオブジェクト全体に適用したくない変数をローカル変数にすると考えました。 その場合、なぜ class A a= 1 end のようにメゾッドに属さないクラス内にあるローカル変数があるのでしょうか?

  • オブジェクト指向コンパイラのインスタンスの構造について

    インタプリタやコンパイラの中身について興味があり勉強しています。といってもまだ簡単な字句解析や構文解析のレベルです。 読んだ本にはオブジェクト指向言語については書かれていませんでした、そこで一つ疑問に思ったこと点について質問させてください。 簡単な言語の場合、使用する変数が宣言されると、その領域がスタックやヒープ空間に確保されるという風に理解しました。 一方オブジェクト指向言語にて、あるクラスのインスタンスを生成した場合を考えます。インスタンスには変数の他に関数やメソッドといった処理手続きが含まれていますよね。その手続きをコンパイルしたコードは何処に置かれているのでしょうか? 手続きのコードもヒープ空間に確保された各インスタンスの領域にコピー(?)されて実行されるのでしょうか。それとも処理手続きの実体は実行プログラムに含まれていて全インスタンスで共通で利用するようになっているのでしょうか。 初心者の素朴な疑問です、ご回答いただければ幸いです。

  • Ruby インスタンスの初期化について

    newメソッドを使わずにinitializeメソッドを定義しただけで インスタンスが作成されて初期化までされる理屈について 教えていただけないでしょうか? またクラスを作るときに基となっているObjectクラスとは一体 何物なのか、教えて頂きたい。 例 01:#Sampleクラスを作る 02:class Sample 03: #Samlpeクラスのインスタンスを初期化 04: def imitialize( lv, hp ) 05: end 06:end ↑の場合インスタンスlvとhpは、「lv = sample.new( 0 )」などと言う ように定義されてない。 それにnewメソッドでインスタンスを作りそこに数値の0を代入できるなら そもそもinitializeで初期化する必要は無いのではないでしょうか? 有識者の方いらっしゃいましたら、ご説明をよろしくお願いします。

    • ベストアンサー
    • Ruby