先輩、オブジェクト指向って何ですか?
わたし、基本的なことが理解できないままプログラミングしているって感じなんです。なんか、モヤモヤしているんです。なにをどう勉強すれば理解できるようになりますか?
萌美ちゃんがわからないのも当然だろうね。だれも正確に教えてくれないし、概念的なことと現実的なことが混在しているから、これで勉強すれば理解できるっていうものじゃないんだ。
オブジェクト指向プログラミング言語をコンパイラとして考えるとコンピュータの基礎から言語の歴史や言語固有の問題点、解決方法といったことまで遡らなければならないんだ。
萌美ちゃんのモヤモヤが完全に解消できるかどうかはわからないけど、ここでは「これからはじめるオブジェクト指向」的な観点で初心者向けで説明してみるよ。
「はい、よろしくお願いします」
―3つの側面―
たぶん、萌美ちゃんはプログラムを書く観点から「オブジェクト指向」が、何となくよくわからないみたいに感じてコードを書いているんじゃないかな。
「そうなんです。インスタンスって何?オブジェクトって何?っていう感じです。
Classをnewでインスタンス化するって意味がわからないままプログラムを書いてます」
《オブジェクト指向には3つの側面がある》
これは、僕がオブジェクト指向を理解しているイメージだと思ってね。
- プログラミング言語=コンパイラという概念面
- プログラムコードを書くというコーディング面
- プログラムをデザインするという実装デザイン面
1つめは、プログラムコードを解釈するコンパイラの仕様的な側面
2つめは、萌美ちゃんがモヤモヤしているコーディング時の側面
3つめは、オブジェクト指向という概念でプログラムの構造をデザインする側面
それじゃ、まず萌美ちゃんがモヤモヤしているコーディング面で考えてみよう。
萌美ちゃん、C#言語が最初に実行される入り口(エントリーポイント)は何かな?
「えへん、それはですね。Main()メソッドです」
正解!!!
Main()メソッドの前に書かれている static は何を意味するかわかるかな?
「調べたことはあります。でも、静的メソッドがなにを意味するかはわかりません」
多分そうだと思ったよ。勉強したくても具体的にどう理解すればいいのか書いてないからね。本家本元のMSDNを普通に読んだら何が言いたいのか、いま読んでみても僕もわからないよ。http://msdn.microsoft.com/ja-jp/library/98f28cdx(v=VS.80).aspx
もし、C#のstatic void Main()メソッド の static がなければどうなるのか?
void Main() {}
当然コンパイルエラーになってしまうのだけど、なぜエラーになるのかわかるかな?
「文法で規定されているからです」
その通り!・・・なんだけど、なぜ規定しているのかな?
「・・・・・・わかりません」
わからなくて当然だからそんなにしょげなくてもいいよ。
コンパイルすると
'Main': 静的クラスでインスタンス メンバーを宣言することはできません。
というエラーが発生するんだ。
このエラーメッセージは、
Main()メソッドがあるクラスが static宣言しているからなんだ。
static class Program → class Programに変更してコンパイルすると《プログラム '*****.exe' は、エントリ ポイントに適切な静的 'Main' メソッドを含んでいません》というエラーを出力してコンパイルを終了するんだ。
Main()メソッドのClassがstaticでなくても
Main()メソッドがstatic宣言されているとコンパイルは通るよ。
class Program { static void Main() { } }
もし、仮にだよ。
Main()メソッドをstatic宣言なしで、
正常にコンパイルが完了したとしたらどうなっていると思う?
果たしてプログラムは実行できるかな?
「それって、単にエラーが出ないだけの状態っていうことですよね。
エントリーポイントのMain()メソッドがない状態でコンパイルが完了したんだから・・・~~~ん。わかりませ~~ん」
萌美ちゃん、惜しいよ!
《実行できるプログラムコードは存在しない》 → これが答え
だから、10万行のプログラムであっても、Main()メソッドがなければ
コンパイラはエラーを出して実行モジュールは作らない(作れない)状態になるんだ。
static宣言は、このメンバーは実行時にすぐに使える(使いますよ)宣言なんだ。
プログラムの実行単位はメソッドだから、最小限Main()メソッドはstatic宣言されていなければならない。そして、C#コンパイラはMain()メソッドをプログラム実行の入り口と決めつけている。
萌美ちゃん、ここまでは理解できた?
「なぜstatic宣言しなけれならないのか、その辺がモヤモヤしてます。
static宣言なしで、はじめからすぐに使えるようにすればいいんじゃないんですか?」
いい疑問だよ。これからそれを説明しようと思ってたところだからね。
でも、萌美ちゃんが思っていることは、C言語で既に半世紀前から存在しているんだ。
いつでも使える=プログラム中に一つしか存在できない=プログラムコードの使い回しができない。static宣言は、アセンブリ中に同じ名前をつけることができない。ユニークな名前でなければならない。
C言語の世界観は、処理(プログラム)とデータを切り離して考えていたんだ。
プログラムに対する要求が高度に複雑になってくると、様々な問題やトラブルの解決にコストがかかりすぎるようになってきた。
そこで、考え出されたのが《処理とデータを一つにまとめる》という概念。
データ操作を様々な関数でおこなうのではなく、データに対する操作を一元化するという考え方だね。
static宣言は、メンバーすぐに使える宣言。
逆に、宣言しなければ”すぐに使えない”という事になるよね。
Classをインスタンス化してObjectを作れば使えるようになる。
たとえば
DateTime dt = new DateTime();
DateTime Classをインスタンス化してObjectを作って使用する。
これってどう言う意味(目的)があるんだろうね?
インスタンス化はClassをそのまま使えるようにするのではなくて、(Classをテンプレートとして考え)Classをコピーして実行できるようにしたんだ。そうすることで、インスタンス化したObjectは、それぞれ独立して扱うことができるんだ。
たとえばこんな感じだね。
DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
DateTime dt3 = new DateTime();
元は同じClassだけれど、実行時は全く別物として扱えるんだ。
Classは、いつでもどこでも好きなときに
いくつでもオブジェクトを作ることができる
「あっ! 先輩、モヤモヤがだいぶはれてきました。
インスタンス化は、Classをコピーして実行できるプログラムを作る
インスタンス化は、同じClassをいつでもどこでも、好きなときにいくつでもオブジェクトを作ることがができる
同じClassで作られたオブジェクトはそれぞれ独立して実行できる
こんな感じでいいですか?」
わかってもらえたようだね。
これからは、プログラミングするときはこのことを意識しながら書くようにして、体に染みこませるようにしていけばいいんだよ。
オブジェクト指向言語の話はまだまだあるけど、今日はこの辺で終わりにしよう。
「せんぱい、ありがとうございました♡」
IT@NET塾
丸山