プログラムを勉強したての頃は「オブジェクト」という言葉が何を意味しているのか全く理解ができなかった。
独学でのみ学習し続けた結果「オブジェクトとは何か」を理解できた(つもりな)ので、僕と同じ様に理解に苦しむ人の助けになればと思う。
QUITA先輩方、ご指摘や訂正がたくさんあると思うのでコメント欄にください。まだまだ理解不足な中投稿していきますのでよろしくお願いします。
#この記事のまとめ
・オブジェクトというのは「相対的な概念」であるということ。
・相対的な概念だから人によって指し示しているものは違うこと。
・つまり文章の前後を紐付けてその人が使っている「オブジェクト」が「変数・関数・インスタンス」のどれのことを言っているのかを理解すること。
・広義の意味でのオブジェクトとは「メイン・メモリ上の実態のこと」
・狭義の意味でのオブジェクトとは「インスタンス」のこと。
・反対にオブジェクトでないものは「クラス」
#オブジェクトというのは相対的な概念であること。
まず「オブジェクトとは何か」と検索すると「現実世界に即したモノに注目した考え方」と表現されていることがある。私は初学者の時、この理解に非常に苦しんだ。どの記事を読んでもなんとも言えないモヤモヤ感がずっと残るのだ。
そこで私と同じ様に初学者の人にはスッキリ理解してほしいと思う。
まず第一に「オブジェクト」というのは”相対的な概念”であり、絶対的概念ではない。ということを頭に入れてほしい。相対的という難解な言葉を使っている様だが、簡単に言えば「人によって”オブジェクト”の言葉の指し示すものが違う」ということだ。
わかりやすくいうと、その文章の前後の文脈から「オブジェクトが何を指しているのか推測し理解する」必要があるということだ。
もっと具体的にいうならば、オブジェクトというのは「インスタンス・変数・関数」のどれかのことを指しているのだ。文脈から”オブジェクト”という言葉をこの3つのどれかに変換して読み進める必要がある。
ではオブジェクトを一言で覚えるならどうすればいいのだろうか。
それは「オブジェクト=メインメモリ上の実態(実際のデータ)」と解釈しよう。
#広義の意味でのオブジェクトというのは「メインメモリ上の実態」のことを指す。
ややこしいことに、オブジェクトというのは「広義の意味」と「狭義の意味」の2つを持っている。
まず結論から言うと
・狭義の意味でのオブジェクト=インスタンスのこと。
・広義の意味でのオブジェクト=メインメモリ上の実体のこと。
私が初学者の時に理解に苦しんだのはこの理解がなかったからだ。検索してよくヒットするサイトには1つめの「狭義の意味でのオブジェクト(つまりインスタンス)」の説明がよくあるがこれだけでは理解が足りない。
実際にWikipediaでオブジェクトについて調べると以下のように書かれている(実は私がオブジェクトが”狭義”と”広義”の意味を持つことを理解したのはこれを読んでからだ。)
「コンピュータ科学の分野において、オブジェクト(英語: object)は、変数、データ構造、関数、メソッドなど、識別子によって参照されるメモリ上の値を意味することがある。
オブジェクト指向プログラミングのパラダイムでは、オブジェクトは変数、関数、データ構造を組み合わせたものを意味することがある。特に、クラスベースのオブジェクト指向プログラミングのパラダイムでは、特に、クラスのインスタンスを指す。」
オブジェクト (プログラミング)-wikipedia
つまり、オブジェクトの正しい理解は広義の意味での”オブジェクト”、つまり「メインメモリ上にあるデータのこと」だ。
安心して欲しい、メインメモリについても後でちゃんと説明するから。
まずメインメモリ上にあるデータのことをオブジェクトというのであれば、狭義の意味でのオブジェクトも納得がいく。なぜなら狭義の意味でのオブジェクトである「インスタンス」はしっかりとメモリ上に存在するからだ。
そして変数や関数もインスタンス化と同時にメモリ上にデータとして実態が存在するため、オブジェクトである。
では反対に、オブジェクト出ないものとは一体なんだろうか。
##「クラス」はオブジェクトではない。
上記で「オブジェクトとは”メインメモリ上の実際のデータ”である」ことを伝えた。では反対にオブジェクトではないものとは一体なんだろうか。
それは「クラス」のことだ。
※Pythonではクラスもオブジェクトらしい。shiracamusさんからのコメントを見て欲しい。
クラスはインスタンス化されて初めてメインメモリ上に実態として存在するようになる。つまりクラスを宣言しただけではプログラムは一切動かないのだ。
クラスについても後日改めて解説する記事を出したいと思う。
誤解と訂正覚悟で伝えるなら、何も初期化(初期値が入力)されていない変数もオブジェクトではない。なぜならそれはメインメモリ上に実態(実際のデータ)として存在していないからだ。
#ここまでのまとめ
ここまでをまとめると以下の3つに要約される。
・オブジェクトというのはメインメモリ上の実際のデータのこと。
・インスタンスはメインメモリ上にデータとして存在するから狭義の意味で「オブジェクト」という。
・クラスはメインメモリ上にデータとして存在しないからオブジェクトではない。
では最後にメインメモリについて簡単に解説しようと思う。
メインメモリというのは簡単に言えば「パソコンの中に入っているプログラムの実行場所」のことだ。プログラムはメインメモリ上にインストール(正確にはロード)されて初めて動く。つまり8GBのメインメモリであれば8GB以上のプログラムを動かすことはできないと言うことだ(現在のPCは性能が高いので8GB以上のプログラムも実際は動かすことができる)
メモリにはデータとアドレスの2つがあるが、これらの仕組みに関しては他の記事を参考にして欲しい。オブジェクトの話に戻ると、メインメモリ上にロードされた実際のデータのことを”オブジェクト”というのであるということだ。
くどいようだが、インスタンスは実際にメインメモリ上に存在するし、変数や関数も値が入っていればメインメモリ上に実際にデータ(0と1のデータ)として存在している。だからインスタンスや変数、関数は全てオブジェクトと呼ばれるのだ。
#以下は個人的なポエム
最後に個人的なポエムを残したい。ただの自己満ありこれまで感じたことだ。
プログラムの勉強には以下の2つが必要だと考える。
・英語力
・低レイヤの理解
まず英語力についてだが、プログラムに限らず世界の共通言語は英語である。そのため日本語だけでの検索・情報収集では世界中の情報の1割にもアクセスすることができない。英語を使えば世界中の情報にアクセスすることができる。
また、英語力が必要な理由の2つ目は、日本語で難解な言葉で書かれていても英語ではとてもシンプルな表現で書かれていることすら多々あることだ。例えばC++での「参照渡しと値渡し」と複雑で直感的に理解しにくい言葉は英語で「Indirect と Direct」と書かれている。これらが対義語であり、かつ英語から何となく動作を想像することができるのである。
英語で検索しろとは言わないが、日本語と英語の両方から情報収集をする様にして欲しい。今の日本語は「漢字、平仮名、カタカナ、和製英語」など入り組んでいてとてもややこしい。これに加えて誰かの造語なども入ってくるからなおさら。
#「低レイヤへの理解」
低レイヤと聞いて想像することは人それぞれだと思うが、私がここで言っているのはただ一つ、「メモリの理解」だ。
メモリの理解をすることでプログラムの動作や原理がある程度わかるようになる。完全に理解しなくていい。ただいつか必ず理解する様に努めて欲しい。
「急がば回れ」と言うが、まさにこのことで、アプリケーションを作って販売して金を稼ぎたいと言う気持ちを抑えて、プログラムの根幹を理解して欲しい。そうすれば今後新たに学ぶ土台となり、なんのプログラムを学ぶにしてもすんなりと入ってくる様になる。
私がプログラムに対する理解にとても有意義だと感じた書籍は日経NETWORKの「プログラムはなぜ動くのか」「なぜオブジェクト指向で作るのか」。
この2冊は伝説的書籍だと思う。
プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識-Amazon
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識
今の時代、大容量なメモリ(こないだ家電量販店で見たのは8GBのメインメモリ搭載のPC)があるためPythonやRubyなどで比較的何もメモリ動作について考えなくてもシステムを構築することができる。
しかしそれは「平成時代」のみを学んでいるに過ぎない、表面的な理解であって真の理解ではないため複雑な(簡単に言うなら「世界を動かす様なシステム」や「高単価なシステム」)を構築することはできないだろう。
平成を理解するには、昭和、明治、江戸などもっと古くを遡る必要がある。PythonやRubyを学び、プログラムが楽しいと思えたなら、Java、C/C++、アセンブリ言語などどんどん低級言語の方に学習をシフトして欲しい。