[備忘録 その１２] Java Silver ～継承とポリモフィズム その１～

# 継承
__継承__ はオブジェクト指向プログラミングの基本的な概念の一つで、既存のクラス(親クラスまたはスーパークラス)の特性を、新しいクラス(子クラスまたはサブクラス)が引き継ぐことを指します。これにより、コードの再利用性が向上し、システムの拡張性や保守性が高まります。
## 継承の基本概念
1 \.__親クラス(スーパークラス)__：継承されるクラス。共通の特性や機能を提供します。
2 \.__子クラス(サブクラス)__：親クラスから特性や機能を継承するクラス。親クラスの機能を引き継ぎ、さらに独自の機能を追加することができます。
```java
// 親クラス
public class Animal {
    void eat() {
        System.out.println("This animal eats food.");
    }
}

// 子クラス
public class Dog extends Animal {
    void bark() {
        System.out.println("The dog barks.");
    }
    
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();  // 親クラスから継承したメソッドを呼び出す
        dog.bark(); // 子クラスで定義したメソッドを呼び出す
    }
}

```

## 継承の利点
1\.__コードの再利用__
* 共通の機能をスーパークラスに定義し、サブクラスでその機能を再利用できます。

2\.__メンテナンス性の向上__
* コードの重複を減らすことで、メンテナンスが容易になります。共通の変更をスーパークラスに加えるだけで、すべてのサブクラスに反映されます。

3\.__ポリモーフィズム__
* サブクラスはスーパークラスの型として扱うことができ、異なるクラス間で共通のインタフェースを持たせることができます。これにより、同じメソッド呼び出しが頃なるクラスで異なる動作をするようになります。

## インタフェースとの違い
* __継承__ ：具体的な実装を持つクラスからプロパティやメソッドを引き継ぎます。
* __インターフェース__ ：メソッドのシグネチャ(メソッド名、引数リスト、戻り値)だけを定義し、具体的な実装は持ちません。クラスは複数のインタフェースを実装できます。
*
### 例：インターフェース
```java
// インターフェース
interface Animal {
    void eat();
}

// 実装クラス
class Dog implements Animal {
    public void eat() {
        System.out.println("Dog is eating.");
    }

    public void bark() {
        System.out.println("Dog is barking.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();   // インターフェースのメソッド
        dog.bark();  // 実装クラスのメソッド
    }
}

```

# オーバーライド
__オーバーライド__ とは、サブクラスがスーパークラスで定義されているメソッドを再定義することです。オーバーライドにより、サブクラスはスーパークラスから継承したメソッドの動作を変更することができます。これにより、同じメソッド名でもサブクラス固有の動作を実現することが可能になります。
## オーバーライドの基本ルール
1 \. __メソッドシグネチャの一致__ ： 
* オーバーライドするメソッドは、スーパークラスのメソッドと同じ名前、引数リスト、戻り値の型を持つ必要があります。

2 \. __アクセス修飾子の制約__ ：
* サブクラスのメソッドは、スーパークラスのメソッドと同じか、それより広いアクセス修飾子を持つ必要があります。例えば、スーパークラスのメソッドがprotectedの場合、サブクラスではprotectedかpublicにできますが、privateにはできません。

3 \. __例外の制約__ ：
* オーバーライドするメソッドは、スーパークラスのメソッドが宣言する例外と同じか、それよりも少ない例外をスローできます。新しい例外を追加することができません。

```java
// スーパークラス
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

// サブクラス
class Dog extends Animal {
    @Override // オーバーライドしていることを示すアノテーション
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        myDog.makeSound(); // "Dog barks" と出力される
    }
}

```
## オーバーライドの利点
1 \.__動的ポリモーフィズムの実現__ ：
* オーバーライドを使用することで、同じメソッド呼び出しが異なるクラスで異なるクラスで異なる動作するようにすることができます。これは、オブジェクト指向プログラミングの重要な概念である動的ポリモーフィズムを実現するものです。

2 \.__コードの再利用__ ：
* スーパークラスの一般的な機能を利用しつつ、サブクラスで特定の機能を上書きしてカスタマイズすることができます。
3 \.__柔軟性の向上__ ：
* クラスの振る舞いを継承しつつ、必要な応じて特定の動作を変更することで、柔軟な設計が可能になります。

### スーパークラスのメソッドを呼び出す
```java
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        super.makeSound(); // スーパークラスのメソッドを呼び出す
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.makeSound(); // "Animal makes a sound" と "Dog barks" が出力される
    }
}
```

# thisとsuper
クラス内のメンバ(フェールドやメソッド)やスーパークラスのメンバにアクセスするために使われます。
## thisキーワード
thisキーワードは、現在のオブジェクトのインスタンスを指します。
1 \.__インスタンス変数へのアクセス__：
* メソッドのローカル変数とインスタンス変数の名前が同じ場合、thisを使ってインスタンス変数を明示的に指定します。

2 \.__ほかのコンストラクタの呼び出し__：
* 同一クラス内の別のコンストラクタを呼び出すために、使用されます。

3 \.__現在のオブジェクトを返す__：
* メソッドチェーンを実現するために使用されることがあります。

```java
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name; // インスタンス変数を指す
        this.age = age;
    }

    public void display() {
        System.out.println("Name: " + this.name); // インスタンス変数を指す
        System.out.println("Age: " + this.age);
    }

    public Person getSelf() {
        return this; // 現在のオブジェクトを返す
    }

    public Person(String name) {
        this(name, 0); // 他のコンストラクタを呼び出す
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);
        person.display();
        Person samePerson = person.getSelf();
    }
}
```

## superキーワード
superキーワードは、スーパークラス(親クラス)のメンバにアクセスするために使用されます。
1 \.__スーパークラスのコンストラクタの呼び出し__：
* サブクラスのコンストラクタ内でスーパークラスのコンストラクタを呼び出すために使用されます。

2 \.__スーパークラスのメソッドの呼び出し__：
* サブクラスでオーバーライドされたメソッドに対して、スーパークラスのバージョンを呼び出すために使用されます。

3 \.__スーパークラスのフィールドのアクセス__：　
* サブクラスで同じ名前のフィールドが定義されている場合に、スーパークラスのフィールドにアクセスするために使用されます。

```java
class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    public Dog(String name) {
        super(name); // スーパークラスのコンストラクタを呼び出す
    }

    @Override
    public void makeSound() {
        super.makeSound(); // スーパークラスのメソッドを呼び出す
        System.out.println("Dog barks");
    }

    public void display() {
        System.out.println("Name: " + super.name); // スーパークラスのフィールドにアクセスする
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.makeSound();
        dog.display();
    }
}
```

最初のページ
[[備忘録 その１] Java Silver ～Javaプログラミング基礎～](https://qiita.com/MagicShowTime/items/9fcf3a2cb4a7162aafcf "[備忘録 その１] Java Silver ～Javaプログラミング基礎～")

前のページ
[[備忘録 その１１] Java Silver ～クラス定義・オブジェクトの使用 その３～](https://qiita.com/MagicShowTime/items/8cca697305bac77a61be "[備忘録 その１１] Java Silver ～クラス定義・オブジェクトの使用 その３～")

次のページ
[[備忘録 その１３] Java Silver ～継承とポリモフィズム その２～](https://qiita.com/MagicShowTime/items/ee6f07ace15ef36a1dba "[備忘録 その１３] Java Silver ～継承とポリモフィズム その２～")