1
1

[備忘録 その12] Java Silver ~継承とポリモフィズム その1~

Last updated at Posted at 2024-08-07

継承

継承 はオブジェクト指向プログラミングの基本的な概念の一つで、既存のクラス(親クラスまたはスーパークラス)の特性を、新しいクラス(子クラスまたはサブクラス)が引き継ぐことを指します。これにより、コードの再利用性が向上し、システムの拡張性や保守性が高まります。

継承の基本概念

1 .親クラス(スーパークラス):継承されるクラス。共通の特性や機能を提供します。
2 .子クラス(サブクラス):親クラスから特性や機能を継承するクラス。親クラスの機能を引き継ぎ、さらに独自の機能を追加することができます。

// 親クラス
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.ポリモーフィズム

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

インタフェースとの違い

  • 継承 :具体的な実装を持つクラスからプロパティやメソッドを引き継ぎます。
  • インターフェース :メソッドのシグネチャ(メソッド名、引数リスト、戻り値)だけを定義し、具体的な実装は持ちません。クラスは複数のインタフェースを実装できます。

例:インターフェース

// インターフェース
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 . 例外の制約

  • オーバーライドするメソッドは、スーパークラスのメソッドが宣言する例外と同じか、それよりも少ない例外をスローできます。新しい例外を追加することができません。
// スーパークラス
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 .柔軟性の向上
  • クラスの振る舞いを継承しつつ、必要な応じて特定の動作を変更することで、柔軟な設計が可能になります。

スーパークラスのメソッドを呼び出す

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 .現在のオブジェクトを返す

  • メソッドチェーンを実現するために使用されることがあります。
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 .スーパークラスのフィールドのアクセス: 

  • サブクラスで同じ名前のフィールドが定義されている場合に、スーパークラスのフィールドにアクセスするために使用されます。
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();
    }
}

最初のページ
[備忘録 その1] Java Silver ~Javaプログラミング基礎~

前のページ
[備忘録 その11] Java Silver ~クラス定義・オブジェクトの使用 その3~

次のページ
[備忘録 その13] Java Silver ~継承とポリモフィズム その2~

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1