c#講座2016softmedia.sakura.ne.jp/w/images/e/e9/2015年度春季C... · 2016. 2. 22. ·...
TRANSCRIPT
C#講座20163日目 アクセス修飾子・ICloneable・Windows Forms
PDF版
クラスの定義
クラスとは?
・設計図!
・C言語の構造体の中に一緒に関数(メソッド)を
定義できるようにしたもの
書き方
class ~~
{
~~
}
オブジェクト指向でより自然言語に近く
クラスの概念により、プログラミング言語もっと自然言語に近い構造に!
C言語など
オブジェクト指向言語
result = convert(A);
proc(B.data);
結果は、数値に変換(Aを)処理(Bのdataを)
result = A.convert();
B.data.proc();
結果は、Aを数値に変換したもの()Bのdataを処理する()
より人間の言語に近い形に!!
オブジェクトは参照型
オブジェクトとは
クラスを元に作成した変数。
設計図から作成した製品。
参照型?
intなど オブジェクトなど
種類 値型 参照型
変数名に関連付けされるもの
メモリ上の実体データ
メモリ上のどこに実体データがあるか
オブジェクトは参照型
int型(通常の変数)
int numberB = numberA;
オブジェクト
Car carB = carA;
numberA「10」 numberB「10」
実体を複製
carA(メモリ上のxxにあるよ!)
carB(メモリ上のxxにあるよ!)
参照先を複製
メモリ上の実体
メモリ上の実体 メモリ上の実体
インスタンス化
メモリ上に実体データを格納できる場所を確保
そして、コンストラクタでフィールド(メンバ変数)などを初期化
要は、設計図を元に新しい製品を作る処理
インスタンス化の流れ
Car car1 = new Car();
識別子(名前)を宣言
メモリ確保
コンストラクタ呼び出し初期化処理
静的クラス ── 変数を作れない設計図
sample02で定義したクラス「Car」はそのクラスを元に変数が作成できる「動的クラス」
変数が作成できない「静的クラス」というものがある
世の中には一つの設計図からたくさんの製品を生産するものと、一つの設計図から一つのものしか作らないものがある。
一つの設計図から大量生産 :「市販の自動車」「スマートフォン」など一つの設計図で一つだけ作る:「東京スカイツリー」など
オブジェクト指向の世界にも一つの設計図で一つだけ作るものが存在する
静的クラス ── 変数を作れない設計図
Console.Write、Console.WriteLine
のConsoleも実は静的クラス。
黒い画面はプログラム1つにつき1つまでしか作れないから、わざわざたくさん変数を作らせる(インスタンス化)させる意味が無い
つまり…
静的クラスを定義すると、同時にその名前の 変数 が作成される!オブジェクト
※正確にはオブジェクト自体が初期化されメモリ上に生成されるのは、その静的クラスの初回利用時
設計図から別の設計図を作る
元になっている設計図が存在し、それを微妙に変更した新しい設計図を作りたい
その場合は「継承」を使おう!
設計図から別の設計図を作る
乗車定員 8人
ボディタイプ 5ドアミニバン
変速機 エクストロニックCVT
エンブレム 日産のロゴ
日産セレナ
乗車定員セレナと一緒!
(セレナから継承)ボディタイプ
変速機
エンブレム スズキのロゴ
スズキランディ
ランディ側の設計図に記述しなくてはいけないのは、エンブレムがスズキのロゴであるということだけ!
※実際にはセレナとランディでは細かい仕様やオプション装備の内容にもっと差異があります。
Sample2-02.cs
忘れてしまった人はもう一度確認してみよう!
まとめ
以上が過去2回の内容
まとめるとこんなあっさりした内容だけど、これが混乱の原因
ここさえ分かってしまえば、オブジェクト指向は怖くない!
衝撃!「実はお前の父は私だ」
継承のお話
自分で継承の記述をしていなくても、実は
「Object」を自動的に継承させられている
すべてのクラスの継承家系図の始祖に
「Object」クラスがいる!
創造神「Object」クラス
すべてのクラスに必要な共通機能を提供
オブジェクトを文字列で表すToString()メソッドなど
ToString()は継承元のObjectで定義されているため、どのクラスでも利用可能ToString()をオーバーライドして、独自の文字列への変換処理を実装することも
自分で定義したクラスのオブジェクトをConsole.WriteLine()に突っ込んだあと、クラスでToString()をoverrideして、もう一度WriteLineの結果を確かめると意味がわかる
アクセス修飾子
オブジェクト指向の醍醐味
「カプセル化」
「隠蔽化」
「外に見せたくないものは見せない。」
「使わせたいものだけ使わせる。」
見せたいもの、見せたくないもの
Sample3-01.csを開いてください!
隠蔽してしまおう
外からアクセスさせたくないフィールド(メンバ変数)は、public ではなく、privateを使うことで外からアクセスできなくなる
オブジェクト指向においては、常に作ったクラスを赤の他人が利用することを想定しながら書くとよい
public と private
アクセス修飾子(アクセシビリティ)という。
今までのサンプルプログラムでは、publicのみを使ってきた
public = 公開する。クラスの外に公開し、どこからでもアクセスできるようにする。
private =非公開。クラスの内部からしかアクセスできなくする。
様々なアクセス修飾子
とりあえずpublicとprivateがわかればよい。
継承をたくさん使う場合は、protectedも覚えよう。
アクセス修飾子 意味
public 完全公開。どこからでもアクセス可能。
internal 限定公開。同じアセンブリ内からならアクセス可能。
protected 限定公開。クラス内部とそのクラスを継承したクラス内からアクセス可能。
private 非公開。クラス内部からのみアクセス可能。
演習1:アクセス修飾子を使おう
実際にアクセス修飾子を使い分けてみましょう。
Sample3-01.csのMoneyBox内のフィールドは現在すべて公開状態。
先ほど説明したトラブルを防ぐために、外部からアクセスさせるべきでないフィールドをprivateにしましょう。
演習2:コンパイルエラー
演習1で非公開にしたフィールドに対して、クラス外部であるメイン関数からアクセスして値を書き換えるプログラムを書きましょう。
コンパイルしてみましょう。
どういう反応になるか確かめてみてください。
演習2 拡張
20xx年、日本政府は円の大幅な下落と物価上昇を受け、「50,000円札」の発行を決定した。
この決定を受けて、MoneyBoxを50,000円札に対応させたいが、「クライアント」の要望により既存のMoneyBox
クラスは残すことになった。
演習2で書き換えたプログラムを元に、既存のMoneyBoxを継承する形で新たにMoneyBoxExクラスを定義し、50,000円札に対応させましょう。
オブジェクトの複製
オブジェクトは「参照型」であるため、値型のように等号記号を使ったり、関数に引数で渡したりしても、実体はコピーされない
オブジェクトの実体をコピーするためにはどうしたらいいでしょう。
クラス側にICloneableを実装
先週取り上げたインターフェイスのお話。
(覚えてないならないで構いません)
オブジェクトの元の設計図となるクラスに「自身の複製を作成する」メソッドを定義する。
carA(メモリ上のxxにあるよ!)
carB(メモリ上のxxにあるよ!)
参照先を複製
メモリ上の実体
carA carB
実体を複製
メモリ上の実体 メモリ上の実体
クラス側にICloneableを実装
等号を使う
carB = carA;
複製用のメソッドを使う
carB = carA.Clone();
記述方法
Sample3-02.csを開いてください。
MemberwiseClone()の特性
自己の複製を作ってくれるメソッド
Objectクラスにて定義されている。(どのクラスでも利用可能)
大人の事情により、Objectクラスでprotectedで定義されている。
(つまり、クラスの外からアクセスができない)
自己の中に含まれる参照型フィールドに関しては、参照先のコピーのみとなる
クラスの定義
クラスとは?
・設計図!
・C言語の構造体の中に一緒に関数(メソッド)を
定義できるようにしたもの
書き方
class ~~
{
~~
}
Sample3-02.cs
まだコンパイルしないで!
先ほどのSample3-01.csのMoneyBoxにICloneableを実装したもの。
(Cloneメソッドを実装)
演習3:実行結果の予測
サンプルプログラムをコンパイルする前に実行結果を予測してみましょう。
演習4:コンパイルと結果の確認
実際にコンパイルして、実行結果を確認してみましょう。
Sample3-03.cs
まだコンパイルしないで!!
新たにSofumemberクラスを定義して、そのフィールドとしてMoneyBox型オブジェクトを持たせた。
演習5:実行結果の予測
プログラムをコンパイルする前に実行結果を予測してみましょう。
Sofumember型のオブジェクトを複製する際、そのフィールドであるMoneyBox型オブジェクトの実体が複製されるのかが重要なポイント
演習6:コンパイルと結果の確認
実際にプログラムをコンパイルして、実行結果を確認してみましょう。
演習6 拡張
Sofumember型のClone()メソッドの中身を工夫して、複製時にフィールドのMoneyBox型オブジェクトの実体まで複製されるようにしてみましょう。
CUIからGUIへ
黒画面でデータいじるのも飽きた
GUIアプリも作ってみよう!
GUIってなに?
GUI…Graphical User Interface (画像のUI)
CUI…Character User Interface (文字のみのUI)
ざっくりいえば、今まで黒画面でいじってきたのがCUI。
C# Direct CompilerみたいなのがGUI。
とりあえずコードを見てみよう
Sample3-11.csを開いてください。
Sample3-11.csをコンパイルして、実行結果を確かめてみよう!
FormクラスとApplicationクラス
Formとは
画面上に表示するフォーム(=ウィンドウ)を初期化、表示、制御するためのクラス
Applicationクラス
表示した後、メインループを自動でやってくれる
Formのカスタマイズとコントロールの追加
通常Form型は、Sample3-11.csのように、そのままインスタンス化するような書き方はしない
Formクラスを継承して、オリジナルのフォーム専用の新たなクラスを定義する。
Sample3-12.csを開いてください!
補足:GUIのコンパイル
今までの方法でコンパイルすると、黒い画面が出てきてしまっていた。
「アセンブリの種類」を「フォームアプリケーション」に変える。
コントロールとは
ウィンドウ上の「ボタン」や「文字列」などのこと
DXライブラリで作った時は、draw系の関数で「描画」した
C#などで「Windows フォーム アプリケーション」を作るときは、
ボタンなどは事前にシステム側で用意されたものを貼り付ける
ボタンの例 文字列の例