#markdown{{ # クラス 型には数値以外にも様々なものがありまた自分で作り出すこともできます。 型を作る機能であるクラスを作ってみます。 ## 定義 クラスを定義します。 ``` class クラス名 { } ``` とすることで作ることができます。 また使う場合は以下のようにします。 ``` クラス名 変数名 = new クラス名(); ``` #### 演習1 クラス宣言 LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.Dump(); } class Class1 { } ``` ## フィールド クラスは内部に変数を持つことができます。 クラス内の変数のことをフィールドといいます。 クラス内で以下のように宣言すると使えるようになります。 ``` アクセシビリティ 型名 フィールド名; ``` フィールドは初期化することができます。 クラスに含まれるフィールドにアクセスするためには以下のようにします。 ``` 変数名.フィールド名 ``` #### 演習2 フィールド LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.a.Dump(); c.a = 10; c.a.Dump(); } class Class1 { public int a = 0; } ``` ## メソッド クラスは関数も持つことができます。 クラス内の関数をメソッドと呼びます。 クラス内で以下のように宣言すると使えるようになります。 ``` アクセシビリティ 戻り値の型名 メソッド名(引数リスト); ``` クラスに含まれるメソッドにアクセスするためには以下のようにします。 ``` 変数名.メソッド名(引数リスト); ``` #### 演習2 フィールド LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.a.Dump(); c.Add(); c.a.Dump(); } class Class1 { public int a = 0; public void Add() { a++; } } ``` ## アクセシビリティ アクセシビリティはクラス内の要素をどの範囲で公開するかを指定します。 アクセシビリティ|説明 ------------|---- public |どこからでもアクセス可能 protected |クラス内部と、派生クラスの内部からのみアクセス可能 internal |同一プロジェクト内のクラスからのみアクセス可能 protected internal|同一プロジェクト内のクラス内部、または派生クラスの内部からのみアクセス可能 private |クラス内部からのみアクセス可能 何も指定しない限りprivateです。 #### 演習3 アクセシビリティ LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.a.Dump(); } class Class1 { private int a = 0; } ``` エラーコード(CSXXXXとなっているところです)を検索してみましょう。 以下の文字を入力し実行しましょう。 ## プロパティ 通常のプログラミングではフィールドはかくしてメソッドを公開します。 なぜならメソッドの内部を書き換えることはできても、フィールドに手を加える事ができないからです。 しかしそれではただフィールドから読み出しだけや書き込みだけのメソッドが大量にできてしまいます。 そこでC#にはプロパティというフィールドの操作に似たことのできる機能があります。 クラス内で以下のように宣言すると使えるようになります。 ``` アクセシビリティ 形名 プロパティ名 { get { 読み込み処理 } set { 書き込み処理 } } ``` プロパティのsetの中ではvalue変数が自動的に定義され書き込むべきデータが入っています。 #### 演習4 プロパティ LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.A.Dump(); c.A=10; c.A.Dump(); } class Class1 { private int a = 0; public int A { get { return a; } set { a = value; } } } ``` またget、setそれぞれにアクセシビリティを指定することが可能です。 #### 演習5 個別のアクセシビリティ LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.A.Dump(); c.A=10; c.A.Dump(); } class Class1 { private int a = 0; public int A { get { return a; } private set { a = value; } } } ``` エラーコード(CSXXXXとなっているところです)を検索してみましょう。 以下の文字を入力し実行しましょう。 現実で使うと上のようにただ変数を読み書きするだけのプロパティをよく書きます。 そこで省略をすることが可能です。 #### 演習5 プロパティの省略形 LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.A.Dump(); c.A=10; c.A.Dump(); } class Class1 { public int A{get;set;} } ``` ## 継承 あるクラスで定義されているものを流用して新しいクラスを作ることができます。 これを継承といいます。 継承は以下のように行います。 ``` class クラス名:継承するクラス名 { } ``` 一度に継承できるクラスは1つです。 #### 演習6 継承 LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class2 c = new Class2(); c.A.Dump(); c.B.Dump(); } class Class1 { public int A; } class Class2:Class1 { public int B; } ``` 継承したクラスは継承元のクラスとして扱うことができます。 しかし使えるのは継承元のクラスの要素のみです。 #### 演習7 継承2 LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class2(); c.A.Dump(); c.B.Dump(); } class Class1 { public int A; } class Class2:Class1 { public int B; } ``` エラーコード(CSXXXXとなっているところです)を検索してみましょう。 以下の文字を入力し実行しましょう。 ## オーバーライド 特定のメソッドまたはプロパティは継承先で書き換えることができます。 これをオーバーライドと言います。 特定のメソッドとはvirtualのついたメソッドです。 #### 演習8 オーバーライド LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c = new Class1(); c.A(); c.A(); c=new Class2(); c.A(); c.A(); } class Class1 { public int a = 10; public virtual void A() { a.Dump(); } } class Class2:Class1 { public override void A() { (++a).Dump(); } } ``` ## 抽象 継承先のクラスで定義してほしいが継承元のクラスでは定義できないということがあります。 この時はクラスを抽象クラスにします。 抽象クラスは要素が未完成のため変数にできません。 #### 演習9 抽象クラス LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Class1 c=new Class2(); c.A(); c.A(); } abstract class Class1 { public int a = 10; public abstract void A(); } class Class2:Class1 { public override void A() { (++a).Dump(); } } ``` ## インターフェース 継承は親クラスが様々な処理を実装しますが、そんなことせずにただメソッドやプロパティは何があればいいかを 決めるだけにしたいことがあります。この定義ができるのがインターフェースです。 インターフェースはいくらでも継承することができます。インターフェースの要素はすべてpublicです。 #### 演習10 インターフェース LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Interface1 i1= new Class2(); i1.A(); Interface2 i2=new Class2(); i2.B(); } interface Interface1 { void A(); } interface Interface2 { void B(); } class Class2:Interface1,Interface2 { int a; public void A() { (++a).Dump(); } public void B() { (--a).Dump(); } } ``` ## 型変換 ある型の変数を別の型の変数にすることを型変換といいます。 型変換は安全な場合(ある数をそれより大きい数が表せる型にする、継承した型にする、型変換が定義されている)に自動で行われます。しかしそうでない場合は明示的に変換する必要があります。 #### 演習11 型変換 LinqPadのLanguageをC#Programにしておきましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { Interface1 i1= new Class2(); i1.A(); Class2 c = (Class2)i1; c.B(); } interface Interface1 { void A(); } interface Interface2 { void B(); } class Class2:Interface1,Interface2 { int a; public void A() { (++a).Dump(); } public void B() { (--a).Dump(); } } ``` 以下の文字を入力し実行しましょう。 ``` void Main() { Interface1 i1= new Class2(); i1.A(); Interface2 i2 = (Interface2)i1; i2.B(); } interface Interface1 { void A(); } interface Interface2 { void B(); } class Class2:Interface1,Interface2 { int a; public void A() { (++a).Dump(); } public void B() { (--a).Dump(); } } ``` 以下の文字を入力し実行しましょう。 ``` void Main() { Interface1 i1= new Class2(); i1.A(); Interface2 i2 = (Interface2)i1; i2.B(); } interface Interface1 { void A(); } interface Interface2 { void B(); } class Class2:Interface1 { int a; public void A() { (++a).Dump(); } public void B() { (--a).Dump(); } } ``` 例外を検索してみましょう。 以下の文字を入力し実行しましょう。 ``` void Main() { double d = 1.1; int i = (int)d; i.Dump(); } ``` ## object C#はすべての型が自動的にObjectを継承します。 Object型のメソッドにToString()があります。 これにより全ての変数は文字にすることができます。 }}