オブジェクト指向 - 用語まとめ -

#1.はじめに
C#の超入門本を読み、オブジェクト指向で出てくる用語がいくつかあったため、内容を整理しアウトプットするためにこの記事を書きました。
そのことから、オブジェクト指向の概要（クラス・インスタンス・カプセル化・継承・ポリモーフィズムなどの）説明は省きます。

#2.用語の説明
##2-1.メンバ変数とメンバメソッド
メンバ変数・・・クラス内で宣言した変数のこと

```C#
インスタンス生成時の変数名.メンバ変数
// 上記のように書くことでメンバ変数を使用することができる
```

メンバメソッド・・・クラス内で定義したメソッドのこと

```C#
インスタンス生成時の変数名.メンバメソッド
// 上記のように書くことでメンバ変数を使用することができる
```

##2-2.コンストラクタ
コンストラクタは、インスタンス生成時にnewの後ろに記述するあれです。

```C#
クラス名 変数名 = new クラス名()
// newの後ろに書かれている クラス名() がコンストラクタです。
```
コンストラクタは、インスタンス生成と同時にメンバ変数の初期値を代入してくれる仕組みです。
クラスには、以下のようにコンストラクタを書くことができます。
例えば、Personクラスがあったとして・・・

```C#
class Person
{
  public int age; //年齢
  public string language; //話せる言語
  //クラス内で宣言したメンバ変数

  public Person()
  {
  this.age = 0;
  this.language = "日本語";
  }
}
//クラス内で宣言したメンバ変数に初期値を設定しているブロックがコンストラクタ
```
コンストラクタは必ずしもクラスに書かなければならないわけではなく、書かなくてもOK。
その場合、コンパイラさんがインスタンス生成時に
_「引数も初期値もない**デフォルトコンストラクタ**を作ればいいのね」_
と、自動で判断してくれるのです。（ありがたいですよね。）

そして、何も書かれていないコンストラクタをデフォルトコンストラクタと呼びます。
もちろん引数ありバージョンで書くなら、インスタンス生成時に引数を渡してあげればOKです。

```C#
class Person
{
  public int age; //年齢
  public string language; //話せる言語

  public Person(int age, string language)
  {
    this.age = age;  
    this.langage = language;
    //インスタンス生成時に渡された引数をそれぞれ代入
  }
}
```

```C#
Person person = new Person(0, "日本語");
```

##2-3.アクセス修飾子
アクセス修飾子は以下３種類。
どれをクラスで使用するかによって、インスタンス生成後にどこからアクセスできるかが決まってきます。
また、これらを使い分けることで、メンバ変数に意図しない値が入れられないようにしたり、使ってほしい機能だけを使ってもらえるようにコントロールしています。

- public
- protected
- private

####public
そのまんまの意味ですが、すべてのクラスからアクセスできる。

####protected
自分のクラス、もしくは派生したクラスだけアクセスできる。
英語の意味は、保護されるや守られるという意味があるので、
身内以外からアクセスできないように保護しているんだなと私は覚えるようにしました。

####private
こちらもそのまんまの意味ですが、自分のクラス内でしかアクセスできません。
ほかのクラスは一切アクセスできないプライベートな場所

書き方は、以下のようになります。

```C#
private int age; 
//アクセス修飾子 型名 メンバ変数名

public void Speak(){ 処理 }
//アクセス修飾子 戻り値の型 メンバメソッド名(){}
//voidは戻り値なしという意味
```

##2-4.アクセサ
アクセス修飾子をprivateにして、変数宣言されたメンバ変数にはほかのクラスから一切アクセスできないようになりました。
これはアクセスできないようにしたかったので問題ないのですが、正しい値を代入したい場合もアクセスできなくなってしまうようです。

そこで、メンバ変数へアクセスできるようにするためのメソッドを用意することになるのですが、これを**アクセサ**と呼びます。

```C#
class Person
{
  private int age;
  //privateになっているので、直接的にageの値を取得することができない

  public Person(int age)
  {
    this.age = age;
  }
  //コンストラクタを記述

  public int GetAge()
  {
    return this.age;
  }
  //アクセサを記述
}
```
```C#
Person person = new Person(20);

person.GetAge();
//GetAgeメソッドを通じて、ageメンバ変数の20が取得できる
```
上記のようにメソッドを通じてメンバ変数にアクセスすることができます。

##2-5.プロパティ
アクセサを作る仕組みのことです。
privateで書かれているメンバ変数は直接的にアクセスできないため、メンバ変数へアクセスしようとするとどうしてもコードが冗長になってしまいます。
冗長になることを防ぐ機能としてプロパティがあるようです。

書き方は、以下のようになります。プロパティ名は先頭大文字で書きます。

```C#
class Person
{
  private int age;
  //privateになっているので、直接的にageの値を取得することができない

  public Person(int age)
  {
    this.age = age;
  }
  //コンストラクタを記述

  public int Age
  {
    set
    {
      this.age = value;
      if (this.age < 0)
      {
        this.age = 0;
      }
    }

    get
    {
      return this.age;
    }
  }
  //プロパティ名の先頭を大文字にして記述
}
```

```C#
Person person = new Person(20);

person.Age += 10;
//PersonクラスのAgeプロパティに代入
Console.WriteLine(person.Age + "歳のときにはアメリカに住んでいたい")
//「30歳のときにはアメリカに住んでいたい」 と出力される
```

##2-6.オーバーロード
引数の数と型が違っていれば、同じ名前のメソッドを複数定義することができます。
このことをメソッドのオーバーロードと呼びます。
また、コンストラクタもオーバーロードすることができます。

以下に例となるコードを記述します。

```C#
class Person
{
  private int age;

  public Person()
  //引数なしのコンストラクタ
  {
    this.age = 0;
  }

  public Person(int age)
  //引数ありのコンストラクタ
  {
    this.age = age;
  }
}
```
引数なしでインスタンスが生成されたときは、引数なしのコンストラクタが実行されます。
引数ありでインスタンスが生成されたときは、引数ありのコンストラクタが実行されます。

##2-7.メソッドオーバーライド
基本クラスから継承したメソッドを派生クラスで定義し直すことができるのが、メソッドオーバーライドです。

オーバーライドするときは**virtual修飾子**を基本クラス側で使う必要があります。
また、**override修飾子**が派生クラス側では必要となります。

```C#
//基本クラス
class Person
{
    public virtual void Speak()
    {
      Console.WriteLine("英語が話せます");
    }		
}
 
//派生クラス
class Japanese : Person
{
    public override void Speak()
    {
      Console.WriteLine("日本語が話せます");
    }
}
``` 
```C#
//基本クラスをインスタンス化
Person person = new Person();
person.Speak();
//「英語が話せます」と出力される

//派生クラスをインスタンス化
Japanese japanese = new Japanese();
japanese.Speak();
//「日本語が話せます」と出力される
```

##2-8.abstractキーワード
派生させることを前提とした中身がないメソッドを定義することもでき、実装する際は**abstractキーワード**を付ける。

```C#
//基本クラス
abstract class Person
{
    public abstract void Write();	
}
 
//派生クラス
class Japanese : Person
{
    public override void Write() //overrideを使って定義し直す
    {
      Console.WriteLine("漢字を書きます");
    }
}
```


#3.参考資料
[【C#の基礎】override修飾子でオーバーライドをする方法](https://www.fenet.jp/dotnet/column/language/1902/)
[書籍：確かな力が身につく C# 超入門](https://www.amazon.co.jp/%E7%A2%BA%E3%81%8B%E3%81%AA%E5%8A%9B%E3%81%8C%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8FC-%E3%80%8C%E8%B6%85%E3%80%8D%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-Informatics-IDEA/dp/4815605394/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=C%23%E8%B6%85%E5%85%A5%E9%96%80&qid=1627202908&sr=8-1)
こちらの書籍結構わかりやすかったので、おすすめです！