int型のオブジェクトってローカル変数と何が違うの?
解決済
回答 7
投稿
- 評価
- クリップ 1
- VIEW 1,250

退会済みユーザー
普段は、C#やPythonを使っています。最近、『独学プログラマー Python言語の基本から仕事のやり方まで』という本で知識の再整理をしているのですが、引っかかったことがあったので質問させてもらいます。
Cなどの手続き型の言語のローカル変数も、C#やPythonなどのオブジェクト指向型言語ではオブジェクトになります。
手続き型っぽく書いてみた場合
public class Hello{
public static void Main(){
int money = 10000;
}
}
オブジェクト指向っぽく書いてみた場合
public class Hello{
public static void Main(){
Person john = new Person(10000);
}
}
public class Person{
public int money;
public Person(int money){
this.money = money;
}
}
ここで疑問に思うのは、上のプログラムのmoney変数がオブジェクトというよりは、文脈的には明らかにローカル変数であることです。
Personクラスのインスタンスとしてjohnというオブジェクトが存在するように、intクラスのインスタンスとしてmoneyというオブジェクトが存在するという解釈もできますが、そう考えると不自然な点があります。
それは、johnというオブジェクトのフィールドを参照するにはjohn.money
と書かなくてはならないのに、moneyというオブジェクトはmoney
だけで割り当てられている値を参照できるということです。本来は、例えば、money.value
(valueはフィールドを参照するのに使われる予約語)のように書かないと参照できないようにするのが統一感があってよいのではないでしょうか。めんどくさいですけど...
Main()のフィールドとして考えられなくもない...(??)
質問したいことをまとめると以下の2点になります。
1.オブジェクトのくせにフィールドを参照しなくていいって内部的にどうなっているの?省略記法として認められているってこと?数値データはどこに格納されているの?
2.この宇宙のあらゆる値は、何らかのオブジェクトのフィールドとして存在するので、上記の「手続き型っぽく書いてみた場合」のプログラムってオブジェクト指向でも何でもないし、オブジェクト指向とは言えない という認識であってますか?
久しぶりに投稿したからか、なぜかラフな文体になってしまいましたが、回答よろしくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+8
非常に大雑把な回答であることをご容赦句ください。
質問者さんに提案ですが、「特定の言語が提供する文法」と「オブジェクト指向の本質」を分けて考えることをお奨めします。
オブジェクト指向の本質を「外部へ提供する機能をそれ自身が持っている自律性のあるプログラムの構成要素」と考えてはいかがでしょう?
フィールドやプロパティーやメソッドはその「オブジェクトが外部へ提供する機能」ですが文法や意味付けが違うのは「使い勝手の差」に過ぎず本質的にそれらは「どれもオブジェクトが外部に提供する機能」であると捉えてもよいと思います。
- a.field
aにfield
という名前の属性をちょうだいというとそれを返してくれる - a.filed = something
aにfield
という名前に特定の値を結び付けておいてというとそれを覚えておいてくれる - a.method(1)
aにmethod
という名前の機能を補助的な情報1を渡して何か計算してもらう - a + b
aに+
という名前の機能を補助的な情報bを渡して何か計算してもらう
みたいな。
フィールドがあるからオブジェクトだとかメソッドがあるからオブジェクトという捉え方を捨てましょう。あるオブジェクトに対して「なんかして」というと希望通りに振舞ってくれるというのが広義のオブジェクトと捉えればいいと思います。
上記のような様々な「機能」を使う側のユースケースに応じて「フィールド」とか「プロパティー」とか「メソッド」といったパターンにわけて利用者に提供しているのは言語設計者が考えてくれていることですが、そのどれが「オブジェクト指向的でどれがそうでないか」はあまり堅く考えなくてよい気がします。
1.オブジェクトのくせにフィールドを参照しなくていいって内部的にどうなっているの?省略記法として認められているってこと?数値データはどこに格納されているの?
数値をオブジェクトとは違うものと捉えることが「固定観念」であってそういう区別を超えたところに本質があると思います。「数値」も「単なるクラスのインスタンス」と整理した言語は多い(最近よく見るPythonとか)ですが、別にそうなっていないC#やJavaやC++でも数値は言語が規定する「クラス」のインスタンスではないかもしれないけど、ある「型」の実体であることには違いはなく「型」は「クラス」と同様「他の種類のものと区別が付けられ、それぞれが特定の機能を持ったもの=広義のクラス」と捉えることができると思います。
2.この宇宙のあらゆる値は、何らかのオブジェクトのフィールドとして存在するので、上記の「手続き型っぽく書いてみた場合」のプログラムってオブジェクト指向でも何でもないし、オブジェクト指向とは言えない という認識であってますか?
この宇宙のあらゆる値はフィールドじゃなくてオブジェクト自身と捉えるのがオブジェクト指向の考え方です。あらゆる値がフィールドと捉えるのは曲解といえましょう。オブジェクトはフィールドがないと値を表せないという固定観念があるようですが、そう捉える必要はないと思います。
だれしも特定の言語の文法から入っていくのでその言語の構文や意味付けにしばられがちです。しかしオブジェクト指向は特定の言語仕様のしばりからは離れた概念だと思います。もちょっと柔軟に(緩ーく)考えてもよいのではないかというのが自分のコメントの趣旨です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+8
まず、「ローカル変数」「グローバル変数」「インスタンス変数」という区分と、「プリミティブ型」「オブジェクト型」という区分は別基準です。オブジェクト型の変数でも、ローカル変数はローカル変数です。
そして、Rubyなど、「整数に至るまでオブジェクト」という言語は実在します。Rubyの場合、概念上は「1を意味するオブジェクト」「2を意味するオブジェクト」のような感じで数値オブジェクトが無数にあって、数の違いはインスタンスそのものの違いとして表されるようになっています。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
面白いですね。
特に指定されないときは、特定のdefault動作を持つ という実装は可能です。
数値らしきもの例えば正規表現で[0-9]+はきっと数字なので、moneyと呼ばれた時には、money._default_()で、money._default_=money.int()と代入時に決める みたいな実装はありえます。言語の実装の方向性として、オブジェクト指向でも、書き方としてオブジェクト指向ではない書き方を許すことは普通です。言語設計を行った人はオブジェクト指向を目指していても、一例としてのコードは全くオブジェクト指向には見えない はありだと思います。
Cでアセンブラっぽく書いてもいいし、ファイル名はa.cppでもgccでコンパイル可能に書くことはできます。だからといってCがアセンブル言語になってしまったり、C++がCになってしまったりはしません。記述されたコードは言語のサブスペックにすぎません。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
オブジェクト指向ではローカル変数
もフィールド
もオブジェクト
をいれる入れ物です。
オブジェクト
はデータ
とメソッド
を一纏めにした「なにか」です。
Person john = new Person(10000);
この文のうち、
10000
はint型のオブジェクトになります。
new Person(10000)
でPerson型のオブジェクトを生成します。
Person john = new Person(10000);
でローカル変数john
に生成したオブジェクトを入れます。
とはいえ、intは値型という若干特殊な型というのも間違いではありません。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
こんにちは。
オブジェクトには、2つの側面があります。
- メッセージをやり取りして操作するもの
- 複数のデータを保持しているもの
例えば、money = 10000;
はmoneyオブジェクトに= 10000
(10000を設定せよ)というメッセージを送っていると捉えることも可能です。その意味では moneyもオブジェクトです。
そして、オブジェクトが2.の性質を持つことは多いですが、これは必須ではありません。物によってはそもそもデータを保持していないものもあれば、1つしか保持しないもの、複数保持するもの様々なのです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
-1
読んでて何を言ってるのかさっぱり分かりませんでした。
ローカル変数という意味だとメソッド内で定義しているものは、プリミティブ型でもオブジェクト型でもローカル変数でしかないと思います。
(そもそもそこを混同しているように見えました)
プリミティブ型は、他のメモリアドレスの参照ではなく、直接メモリにもつルールであり、それ以外はメモリ領域への参照アドレスを持つってだけで、new演算子によりメモリ確保され、実体化されるだけの話しでしかありません。
cもjavaもc#も、基本的にバイナリでしか値を持っていないわけで、その最小単位をプリミティブ型として名付け、定義してるだけだと思います。
オブジェクト指向とは、そのメモリ領域に意味を持たせるのとともに、オブジェクトが行うべき作業をメソッドとして定義出来るようにして、構造を分かりやすくしているだけです。
また、細かい内容はオブジェクトに内包させることで抽象化出来ている点がオブジェクト指向の優れたところです。
オブジェクトに内包させて抽象化し、外部から直接見る必要がなくなるので、インターフェースや継承が可能となり、インターフェースだけ分かっていれば、中身をわかってなくても良くなるわけだし、インターフェースにおいては、別オブジェクトを注入されていれば、呼び出し側で同じ処理を呼び出したとしても振る舞いが変わります。
それが便利なポイントです。
c言語だと、構造体が似たようなイメージですが、同じようには行かず、メモリと直接紐付いてしまっているため、抽象的なつくりが難しくなってしまいます。
また、構造体にはメソッドが無いので、単なるデータの集合体でしかないため、ロジック部分は外部に記述されている必要があります。
オブジェクト志向は、読んで名の通り、物質と同じで物に例えられます。
空気で例えると、
・空気という抽象的なインターフェースがあり、
・空気の一部には酸素というオブジェクトがあり、
・酸素じゃないオブジェクトも空気と呼びます。
・酸素を構成するのはH2Oという原子(最小単位)があります。
・空気は移動するという性質(メソッド)があり、
・人がうちわを仰ぐと空気は移動します(メソッド呼び出し)
つまり、最小単位は素粒子(メモリ)とかですが、原子(プリミティブ型)を最小単位と誰かが決めたわけです。
なので、int自体も数字という性質を持つ最小単位のオブジェクトな訳です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
-2
おおーぴについてさんこうになりました!
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.22%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/04/12 20:37
ご指摘の通り、私は固定観念に強く縛られているのかも知れません。
数値もPersonクラスのインスタンスも
> ある「型」の実体であることには違いはない
というように広義にオブジェクトを捉えることで、オブジェクト指向の本質を理解することにつながるのではないかと思います。
ただ、オブジェクトを広義に捉えすぎると、名前や身長などのオブジェクトの属性として考えた方が直感的で理解しやすいものまでオブジェクトになってしまう弊害があるように思います。難しいですね…
実体という表現のイメージが、「何らかの物理的な形・体積を持っているもの」という印象を与えるので、instanceという単語に実体という和訳を与えたのが混乱の元凶なのかも知れませんね。
2018/04/12 20:48 編集
それは自分には特定の言語に慣れたための感覚ではないかと思えます。C++などがintをクラスのインスタンスではなく型の実体にしたのは多分「効率上の問題」あるいは「Cとの互換性」のためで、それさえなければintが組み込みクラスになっていただろうと思います。maisumakunさんがあげておられるrubyや自分があげたpythonの他大御所(?)のsmalltalkなど「あらゆるデータがオブジェクト」の言語はよくあります。そういう言語でintがクラスのインスタンスであることが混乱につながるようには思えません。それが直感的でないと感じるのはintがクラスのインスタンスでない言語に慣れたからそう思えるだけだと思います。
2018/04/12 22:38
まとめると、
オブジェクトが子オブジェクトを持つこともあるから、int型のオブジェクトみたいに子オブジェクトを持ってない場合もあるよって感じですかね?
それとも、int型のオブジェクトは、数値オブジェクトを子オブジェクトとして持つって感じでしょうか?
長々とすみませんm(_ _)m
2018/04/12 22:53 編集
かも知れませんね。自分もアセンブラから始めましたので途中質問者さんのような感覚を感じていた時期もある気がします。
> (A)子オブジェクトを持ってない場合もある
> (B)数値オブジェクトを子オブジェクトとして持つ
自分はどっちかというと(A)と捉えます。もちろん内部的に整数値を保持しているのは確かでしょうから、(B)の捉え方だっていいと思います。ただそう考えてしまうと「じゃぁそのフィールドオブジェクトはどのクラスのインスタンスなん?」と考え始めてしまい、堂々巡りになるので例え内部の実装が(B)であったとしても(A)と捉えることにしてます。
2018/04/13 01:30
すごく腑に落ちた気がします。ベストアンサーに選ばせていただきました。