はじめに
自身がC#を初めて学習する際、プログラミング初学者には少し分かりにくい概念と感じたためこの記事でクラス,コンストラクタ及びインスタンスの概念とインスタンス生成、利用までの流れを丸っと説明しようと思います。
この記事を執筆、掲載することで自身の理解を再度補強すると同時にプログラミングを学習している初学者への助けになれば幸いに思います。
目次
- そもそもクラスとは?
- インスタンスとは?
- クラスの定義からインスタンスの利用まで
- まとめ
1.そもそもクラスとは?
インスタンスという概念を説明する前にまずインスタンスの概念を理解する上で必須となるクラスという概念について説明します。
クラスというのは一言で言うとオブジェクト指向言語における同じ種類のデータや動作をひとまとめに定義したもの、つまり設計図のようなものに当たります。
例えば
人間を表現するクラス→名前や年齢、身長等の情報を含む
車を表現するクラス→運転手や同乗者、荷物、走る動作等の情報を含む
といったようなものです。
ちなみに上記の例で言うところの名前や運転手などのそのクラスが持つデータをプロパティと呼び、走るなどのそのクラスが行う動作をメソッドと呼びます。
以下はC#でクラスを定義する際の実際のコードです。
ちなみに上記のコードの中にコンストラクタというものが出てきておりますが、これは
このあとの項で説明するインスタンスを生成する際に自動的に呼ばれる初期処理を行うメソッドになります。
コンストラクタは
クラスに含まれるプロパティの初期値を設定する
という役割があります。
クラスを設計図とするならばコンストラクタはその設計図に具体的な値を設定する設計者のようなものと言えるでしょう。
2.インスタンスとは?
簡単にですが前項でクラス及びコンストラクタというものの概念について説明しました。
クラスは設計図に当たるデータのため各種色々な情報を内部で定義することが出来ますが、あくまで設計図のためそれ単体では使用できないという仕様になっております。
そこでこのクラスを実際に使用できるようクラス(設計図)から実体化させたものが
インスタンスになります。
前項同様、このインスタンスを人と車に例えると
人クラスから生成されたインスタンス→名前、身長等の情報を持つ具体的な個人
車クラスから生成されたインスタンス→運転手や走行距離といった情報を持つ具体的な車
といった形ですね。
このインスタンスには以下のような特徴があります。
1. 複数生成が可能
1つの設計図(クラス)からインスタンスは何個でも作成可能。
2.独立したデータ領域を持つ
同じクラスでも個別に定義されたインスタンスはそれぞれ別々のオブジェクトとして扱われる。
ちなみにクラス、コンストラクタ、インスタンスこれらの概念がプログラミング初学者にとって何故取っつきづらいかについてですが、主に以下の3点が原因なのではないかと思います。
コンストラクタの役割が直感的ではない
コンストラクタはインスタンス生成時に初期化を行うものですが、
クラスと同じ名前であり、かつクラス内部で定義されているためクラスと混同しやすく具体的にどういった役割を担っているかがパッと見で分かりづらい
メモリ上としての存在なため把握しづらい
newキーワードによって生成されたインスタンスはそれぞれメモリ上の別々の領域に保存されるが、それが可視化されにくく、かつプログラム上では単なる変数のため実体がない存在のように感じられる。
設計図としてのクラス、コンストラクタと実体であるインスタンスの分離のイメージが弱い
インスタンスを生成する際、
Person person1 = new Person("山田太郎", 30);
こういったコードにより生成するが、
Person→クラス person1→インスタンス(変数) new Person(...)→コンストラクタとなっており三者が同一な存在に見える
つまりこの3点に注意すればこれら概念の関係性は一層理解しやすいものになるかと思います。
ここまで説明してきたクラス,コンストラクタ,インスタンスそれぞれの概念と関係を図示すると以下のような図になります。
3.クラスの定義からインスタンスの利用まで
前項までクラス及びコンストラクタとインスタンスの概念について説明してきました。
この項では実際にクラスを定義するところからインスタンスの生成、及びインスタンスの利用まで含めた一連の流れを実際のコード(C#)で説明していきます。
クラスの定義
上記コードは年齢と名前という情報を有する人に関するクラスを定義しているコードになります。
まずはPersonクラスを定義し、その内部でそのクラスが有するプロパティName,Ageを定義します。
プロパティを定義している箇所に{ get; set; }と記載されておりますが、
こちらは自動プロパティといいバックフィールド(クラス内部の変数)の管理をC#が自動的に行うプロパティです。通常、プロパティには内部的な変数が存在しますが、自動プロパティではそれを省略することが出来、このように1文で記載することができます。
簡潔に説明すると
変数名(インスタンス).プロパティ = ○○; とした場合、自動プロパティ内のsetアクセサーが呼び出され、インスタンスのプロパティに○○がセットされます。
一方で変数名(インスタンス).プロパティを呼び出すと自動的にgetアクセサーが呼び出され、内部の値が戻り値として返されるといったようなものです。
この自動プロパティに関してはこの記事ではあまり深追いしないためここでは自動プロパティとして定義すればコードの記述が楽に済むぐらいの認識で大丈夫です。
次にインスタンス生成時に呼び出されるコンストラクタを定義します。
コンストラクタの名前はクラス名と同じものにする必要があり、このコンストラクタによりクラス内のプロパティの初期化処理を行います。
ちなみにC#においてはコンストラクタを定義しなかった場合、自動的にデフォルトコンストラクタが追加されます。(下記コード参照)
この場合、インスタンス生成時に引数も渡せず、プロパティの値も設定できません。
最後にNameとAge変数により自己紹介文を生成するIntoduceメソッドをクラス内に定義しております。
クラス内で定義することにより他のクラスから変数名(インスタンス).メソッドによっていつでも呼び出すことができるようになります。
インスタンスの生成と利用
先ほど定義したクラスとは別のProgramクラス内でPersonクラスのインスタンスを生成します。
インスタンスは
クラス名 変数名 = new クラス名(引数);
のコードによって生成されます。
このとき、name と age の値がコンストラクタに渡され、Name と Age が初期化されます。
そしてperson1 と person2 という変数にインスタンスが代入されます。
変数名(インスタンス).プロパティによりそのインスタンスに紐づいているプロパティの値を取得することができます。
person1.Name
→ person1 が持つ Name プロパティの値("山田太郎")を取得し表示。person2.Age
→ person2 が持つ Age プロパティの値(25)を取得し表示。
上記と同様、変数名(インスタンス).メソッドによりそのインスタンスに紐づいているクラス内のメソッドを呼び出すことができます。
person1.Introduce()
→ person1というインスタンスが持つ Name プロパティの値とAgeプロパティの値でIntroduceメソッドを起動。
簡単に説明しましたが、以上がクラスの定義からインスタンスの生成、及びインスタンスの利用までの一連の流れとなります。
4.まとめ
ここまでクラス、コンストラクタ及びインスタンスの概念と実際にクラスの定義からインスタンスの利用するまでの流れを説明してきました。
まとめるとクラスは設計図、コンストラクタは設計者、インスタンスはそこから生まれる具体的なオブジェクトのようなものであり、これらは三位一体なものだということです。
これらクラスやインスタンスはオブジェクト指向言語における基礎に当たる部分ですが、この辺りの概念や関係を理解することでオブジェクト指向言語におけるオブジェクト指向の考え方がより一層クリアなものになろうかと思います。
本記事は以上になりますが、この記事がプログラミング初学者にとっての理解の助けになれば幸いに思います。
著者: T.M (株式会社ウィズツーワン)