この章では抽象クラスについて説明します。
抽象クラスとは親クラスで大まかなことだけを定義するクラスのことを言います(だから抽象と言う名前が付いています)。
具体的なことはその抽象クラスを引き継いだ各クラス内で決めます。
抽象クラスは親クラス名の前にが付いたクラスであり、抽象クラスの中のメソッドは名前だけ決めて(中身は何も書きません)、メソッドの内容はこれを継承したクラスに書きます。
このようなメソッドを抽象メソッドといいます。
では例をみてみましょう。 抽象クラスの基本構文は以下の通りです。 抽象クラスにしたいクラスには「abstract」を「class」の前に付けます。
さらに中身が決まっていない抽象メソッドの宣言にも「abstract」を付けます。
この例の中では以下の2行が抽象メソッドになります。 抽象メソッドが1つでも含まれているクラスは抽象クラスになります。
また、抽象クラスには普通のメソッドも記述出来ます。
つまり、抽象クラスには抽象メソッドでないメソッドも書くことができます。
抽象メソッドでない普通のメソッドは継承するクラスでもわざわざクラスごとに内容を変える必要が無いメソッドなので、普通のメソッドにしているわけです。
この例ではsleepメソッドを抽象メソッドにしないで、普通のメソッドにしていますが、「夜に寝る」は継承されたクラスで変える必要が無いので普通のメソッドにしています。
抽象メソッドのeatは動物ごとに食べるものが違うので、eatと言うメソッド名だけ決めて、後の具体的な内容は抽象クラスを継承したクラスの中で書くという形を取ります。
抽象クラスを継承したクラスは、この抽象メソッドを必ずオーバーライドしなければなりません。オーバーライドしないとコンパイルエラーとなります。
ですので のように抽象メソッドの宣言をしましたら、以下のように継承したクラスで実際の具体的な内容を記述してください。 抽象メソッドを受け継いだメソッドにoverrideを付けるのを忘れないでください。また、抽象メソッドにvirtualを付ける必要はありません。 抽象クラスについて補足します。
この例の場合 Animalクラスを継承してCatsクラスやDogクラスを定義していますが、この他にもTigerクラスなど他にもクラスが増える可能性もあります。
このように拡張する可能性があるのでAnimalクラスですべてメソッドの中身などを決める必要はないわけです。
つまり、それぞれ動物には特色があるのでAnimalクラスですべての具体的な動きなどを決められないわけです。
Animalクラスで抽象的な名前だけ決めて、後の具体的なことは継承したクラスに任せるとした方が大きいプログラムの場合には使い勝手が良くなります。
他の例を挙げますが、ゲームのプログラムを作るとします。
その時に魔法メソッドを抽象メソッドにして、具体的な魔法の動きは抽象クラスを受け継いだクラスに書くという使い方も出来ます。
結果は以下の通りです。
月: 2015年5月
デストラクタについて知ろう
クラスの継承について知ろう
この章ではクラスの継承について説明します。
クラスの継承とは親クラス(元のクラス)の他に、もう1つの関連したクラスを作ろうとした時に、親クラスのフィールド変数やメソッドを引き継ぐことを言います。
もう1つの関連したクラスのことを子クラスもしくはサブクラスと言います。
親クラスと同じフィールド変数やメソッドを子クラスで定義しなくてはいけない時、同じフィールド変数やメソッドを子クラスで再度記述する必要はありません。
また、子クラスには独自のフィールド変数やメソッドも追加することもできます。
では例を見てみましょう。Banksystemクラスが親クラスで、Securitiesクラスが子クラスになります。
SecuritiesクラスはBanksystemクラスを継承しているので、Banksystemクラスのフィールド変数やメソッドを使用することが出来ます。子クラスの中で親クラスのフィールド変数を使うことができると言いましたが、それが以下の箇所です。他にもstockbuyメソッドやstocksellメソッドの中でも使われています。また、子クラス独自のフィールド変数やメソッドを書くことができると言いましたが、それがcompany変数やstockbuyメソッドやstocksellメソッドやresultメソッドです。
改めて親クラスのメソッドやフィールドを子クラスで書く必要はありませんが、この例では1つだけ親クラスと共通のメソッドを書いています。それはresultメソッドです。このように子クラスと親クラスで名前が同じで、内容だけが違うメソッドを作ることが出来ます。
つまり、メソッド名は変えずに、子クラス独自の内容に変えることが出来ます。
これをオーバーライドと言います。次にprivate とprotectedについて説明します。
親クラスでprivateが付いているフィールド変数やメソッドは子クラスからはアクセスすることはできません。
例の親クラスのフィールド変数を以下のようにprivateに書き換えると子クラスのメソッドから使用することは出来なくなります。ですので、この例では以下のようにprotectedを付けて、子クラスでも使えるようにしています。
protectedは子クラスから親クラスにアクセスできることを意味します。結果は以下の通りです。次は子クラスから親クラスのコンストラクタを呼び出す例です。結果は以下の通りです。では子クラスから親クラスのコンストラクタを呼び出す方法について説明します。
Mainメソッド内で子クラスのオブジェクトを作成し、ここで親クラスや子クラスのフィールド変数にデータを入れています。上のように子クラスであるUsedクラスのオブジェクトが作られた時にはまず初めに自動的に親クラスの引数の無いコンストラクタが呼ばれます。つまり親クラスに引数のあるコンストラクタだけで、引数の無いコンストラクタが無い場合はエラーになります。
親クラスの引数の無いコンストラクタが呼ばれた後に子クラスのコンストラクタが呼ばれることになります。
この例の場合にはコンストラクタの中でさらにsetfieldメソッドを呼び出して値のチェックをしています。
このような書き方も出来ますので覚えておいてください。自動的に親クラスの引数の無いコンストラクタが呼ばれると書きましたが、では親クラスに引数の無いコンストラクタが無い場合エラーになるのだとしたら、どう対処したらいいでしょうか?
方法は2つありますが、1つ目はこの例のように親クラスに引数の無いコンストラクタを作っておくことです。
2つ目は子クラスのコンストラクタの中で親クラスの引数のあるコンストラクタを呼び出す方法です。子クラスコンストラクタの中の引数には親クラスと子クラスのコンストラクタの引数を型も含めて記述します。
baseの中にある引数は親クラスの引数のあるコンストラクタに渡しますが、ここの引数には型名を入れる必要はありません。
では先ほどの例を2つ目の方法で書き換えてみましょう。オブジェクトを作成した時にコンストラクタが実行されますが、n, a, bが親クラスのコンストラクタの引数に入ります。
そしてs, fが子クラスのsetfieldメソッドの引数に代入されることになります。
図にすると以下のようにデータが入ります。結果は以下の通りです。
静的変数、静的メソッドについて知ろう
この章では静的変数、静的メソッドについて説明します。
静的変数・静的メソッドはオブジェクトを作成してから使用するのではありません。
つまり、静的変数・静的メソッドはオブジェクトに属しているのではなくクラスに属していると言えます。
詳しい説明は例の後で行ないます。
では例を見てみましょう。 フィールド変数やメソッドを宣言する時に「static」を付けると静的変数、静的メソッドになります。 これまで使用してきたフィールド変数やメソッドはオブジェクトを作ってから使用しましたが、「static」を付けた変数やメソッドはオブジェクトを作成しなくても使用することが出来ます。
つまり、静的変数、静的メソッドはオブジェクトに属しているのではなく、クラスに属しているのです。
ですので、静的変数にアクセスするにはクラス名を使って(クラス名と変数名の間にはドットがあります)という形式で書きます。 ではこの静的変数をカウントしている箇所はどこかと言いますと以下で静的変数をカウントしています。
つまり、コンストラクタが呼び出されるたびに静的変数であるcount1に1を足しています。 もう一か所静的変数を出力している箇所があるのですが、それがresultメソッドです。ここでもcount1変数がカウントしているのが分かります。
静的変数も変数の一種ですので、普通のメソッドの中で使う事が出来ます。 結果は以下の通りです。 次は静的メソッドの例をみてみましょう。 静的変数の例ではコンストラクタで静的変数に足していましたが、この例では静的メソッドで静的変数に値を足しています。 静的メソッドを実行する場合にはという構文で書きます。
この例では以下の箇所です。
Ginkou.count();
この例では2回静的メソッドを実行しているので実行するごとに1が足されます。
静的メソッドで気を付けなければいけないことは静的メソッド内ではthisを使う事ができませんし、フィールド変数も使う事ができません。
結果は以下の通りです。
プロパティについて知ろう
この章ではプロパティについて説明します。
クラスの中でフィールド変数の値を代入するsetメソッドと値を返すだけのgetメソッドについて説明しました。
それが以下のようなメソッドです。 この2種類のメソッドをフィールド変数ごとに書くのは可読性が悪くなる可能性があります。
これをプロパティを使うことによって書き換えると1種類のプロパティで済みます。
このプロパティはメソッドのようでもあり、フィールド変数のようでもあります。つまり、メソッドとフィールド変数の中間の存在です。プロパティの構文は以下の通りです。 この構文の中のvalueにはプロパティに入れたデータが入りますが、どのように入れるのかと言いますとという構文で入れます。
次の例では以下の箇所です。 では例をみてみましょう。 結果は以下の通りです。
コンストラクタについて知ろう
この章ではコンストラクタについて説明します。
コンストラクタはオブジェクトを作成すると同時に自動的にフィールド変数にデータを入れる特殊なメソッドです。
詳しい説明は例の後に行います。
では例をみてみましょう。 これまでは以下のように1つ1つデータを入れていましたが、実際の銀行のシステムではこの中のどれか1つでもデータを入れ忘れたら大変なことになります。 しかし、コンストラクタと呼ばれる特殊なメソッドを使うことによって、オブジェクトを作成すると同時に自動的にフィールド変数にデータを入れることができます。
以下がコンストラクタの基本構文です。 コンストラクタには戻り値の型を書きません。
例では以下の箇所がコンストラクタです。 次にコンストラクタを呼び出す方法について説明します。
オブジェクトを作成するとコンストラクタが自動的に実行されるのですが、渡したいデータはオブジェクトの引数に入れます。
この例では以下の箇所です。 つまり、オブジェクトの作成の過程でのデータがコンストラクタのにそれぞれ自動的にセットされることになります。
図にすると以下の通りです。
次は引数のあるコンストラクタと引数のないコンストラクタを両方作った例をみてみましょう。 結果は以下の通りです。 前の例では引数のあるコンストラクタだけでしたが、この例では引数のないコンストラクタも同時に作成しています。
このように引数の数や引数の型が違うならば、同じ名前のコンストラクタを定義することが出来ます。
この例では上のコンストラクタは引数がなく、下のコンストラクタは引数が3つあり、引数の数が違いますので同じ名前のコンストラクタでも定義することが出来ます。これをオーバーロードと言います。
コンストラクタの実行はオブジェクトの引数に応じて呼び出されます。
=>ここでは引数のあるコンストラクタを呼び出しています。
クラスについて知ろう
この章ではクラスについて説明します。
今までのプログラムでは変数とメソッドを扱ってきましたが、クラスと言う機能を使うことで、多くの変数とメソッドを1つの機能体として働かせてデータを処理することが出来ます。
クラスとは何かしらの物を作る設計図に例えられます。
設計図は車や家や鉛筆をつくる場合に必要ですが、この設計図に当たるものがクラスです。
車や家や鉛筆の中には色々な部品が含まれていますが、それらの部品には「状態」や「ふるまい」があります。
例えば、鉛筆であれば、「状態」は鉛筆の形、芯、線の濃さなどで、「ふるまい」は線を引く、削るなどの動作です。
その「状態」や「ふるまい」をクラスと言う設計図に書いていきます。
「状態」を「変数」で書き、「ふるまい」をメソッドで書くことになります。
どのような「状態」や「ふるまい」を作りたいかはオブジェクトの役割です。
例えば「線を引く」「線を消す」など具体的な指示をオブジェクトと言う司令塔から出します。
クラスの構文は以下の通りです。 クラスの中に変数やメソッドを書いていきます。
クラスの中の変数をフィールド変数と言います。
次にアクセスレベルについて説明します。
アクセスレベルとは変数やメソッドで使われますが、それらの変数やメソッドに対して、どこからアクセスできて、どこからアクセスできないかを決める修飾子です。
次はオブジェクトについて説明します。
オブジェクトはnew演算子を使って作成します。
オブジェクトとはクラスの中の「状態」を表す変数や「ふるまい」を表すメソッドに指示を出す役割があります。
例えば「線を消す」など具体的な指示をオブジェクトと言う司令塔から出します。 オブジェクトを作る過程をインスタンス化と言います。
ではクラスで作ったプログラムの例を見てみましょう。 このプログラムは銀行でのお金の入金や出金のシステムを簡潔に作っています。2つのクラスがありますが、1つはMainメソッドのあるProgramクラスで、もう1つはGinkouクラスです。
初めにプログラムが実行されるMainメソッドのあるProgramクラスが司令塔になって、他のクラスに指示を出していくことになります。 クラスのフィールド変数には以下の構文でデータを入れます。 クラスのメソッドを実行するためには以下の構文で行います。 その結果、それぞれ以下のメソッドが実行されます。 これらのメソッドはインスタンス化(オブジェクトが作られてから)されてから実行されるのでインスタンスメソッドと呼ばれています。
それぞれのフィールド変数にデータが入ったところで、最後にresultメソッドで出力しています。
結果は以下の通りです。 この例ではProgramクラスを消して、Ginkouクラスにまとめています。
次はアクセスレベルのprivateについて説明します。
これまでのクラスのフィールド変数はpublicにしていますが、これは本来はよろしくありません。
クラスの外側から直接値を入れることが出来てしまうからです。
そこで、フィールド変数はprivateにして、メソッドからこれらのフィールド変数に値を入れる方が最良です。
そして、メソッドはpublicにするのが基本です。
例を見てみましょう。 この例ではすべてのフィールド変数にthisを付けていますが、前の例のように省略が出来ます。
この章では文字列を操作するメソッドについて説明します。
これまでは自身でメソッドを作成してきましたが、C#には初めから機能が定義されているメソッドが複数あります。 =>CompareToメソッドは2つの文字列のデータを比べて、等しければ0を返し、aがbより大きければ0より大きい整数を返し、aがbより小さければ0より小さい値を返します。
では例をみてみましょう。 この例ではaとbは等しいので、0が返ってきますので、結果は「等しい」が出力されます。 =>IndexOfメソッドは文字列aの中から文字列bの位置を先頭から検索して、見つかった場合にはその文字列の位置番号を返します。
その文字列が見つからない場合には-1が返されます。 =>LastIndexOfメソッドは文字列aの中から文字列bの位置を後ろから検索して、見つかった場合にはその文字列の位置番号を返します。
その文字列が見つからない場合には-1が返されます。
では例をみてみましょう。 =>Containsメソッドは文字列aの中に文字列bの文字列が含まれている場合には「TRUE」が返されます。
では例をみてみましょう。 =>IsNullOrEmptyメソッドは文字列がnullかどうか もしくは文字列に何も入っていないかどうかを調べるメソッドです。
nullもしくは文字列に何も入っていない場合にはTRUEを返します。
nullは何のデータもないと言う意味です。
カラの文字列を表現するにはダブルクォートを連続して2つ書きます。
では例をみてみましょう。 結果はaには何も入っていないので「yes」が出力されます。
星座判定をメソッドで作ろう
「if文で星座を判定をしよう」の章ではif文で星座判定のプログラムを作成しましたが、これをメソッドを使って書き換えます。 例えばmonthに1が入り、dayに19が入っているとします。
そうするとの箇所はiが0の時にifの条件式がtrueになりますので、以下の入れ子のif文の条件式の判定に入ります。 「day <= day1[i]」の中のdayには19が入り、「day1[i]」にはday1の0番目の要素である19が入っていますので、条件式はtrueになり、nameにはnames配列の0番目の要素であるやぎ座が入ります。
例えばdayに19ではなく23が入っていると仮定するとはFALSEになるので、の条件式の判定に入ります。
ここで「day2[i]」にはday2の0番目の要素である31が入っていますのでTRUEになり、nameにはに該当する星座が入ります。
1周目ではのiには0が入っていますのでとなり、nameにはみずがめ座が入ることになります。
ここで の説明をします。
「i +1」の箇所の説明をしますと例えばmonthが1で、day が23の場合には
が「23<=19」になり FALSEになるので elseifのブロックに入りますが、 1月はやぎ座と水瓶座しかなく、 やぎ座ではないのならば水瓶座 しかないのでnames配列を 1つ進めるために「i +1」で1を 足しています。
「%12」を記述している理由はの中のiに11が入ると「(i +1)」の箇所が 12になりますが、「%12」の箇所が 無いと仮定するとnames[12]となってしまいますが、実際にnames[12]という 要素はありません。
そこで「%12」で余りを0(12割る12で余り0)にして
「やぎ座」が出るようにしています。
つまり、該当する以下の余りの数字がnames配列の添え字になり、その該当するデータがnameに入ります。 結果は以下の通りです。