🦔

👶「extendsとimplementsってなんですか?」

に公開

プログラミングにおいて、クラスの継承やインターフェースの実装は、コードの再利用性や柔軟性を高める上で非常に重要な概念です。

特に「 extends 」と「 implements 」は、その目的と役割が異なります。

extends (継承)

extends は、あるクラスが別のクラス(スーパークラス)から機能を引き継ぐときに使います。

言い換えると、「何をするか」も「どうやってやるか」も、親がすでに決めてくれているパターンです。子ども(サブクラス)はそのまま使えます。

class Animal {
  void eat() {
    print("食べる");
  }
}

class Dog extends Animal {
  void bark() {
    print("ワンワン");
  }
}

void main() {
  Dog dog = Dog();
  dog.eat();  // Animalクラスのメソッドを呼び出し
  dog.bark(); // Dogクラスのメソッド
}

このように、Dog クラスは Animal クラスの eat() メソッドをそのまま使うことができます。

「どんなことをするか」まで親(継承元)が決めてくれるので、子(継承先)としてはちょっと窮屈かも。でも、「私はこうするのよ!( オーバーライド )」もできます😮‍💨

単一継承 : 1つのクラスは1つのクラスしかextendsできません。
実装の再利用 : メソッドやプロパティをそのまま利用したり、必要に応じて オーバーライド(上書き) もできます。
共通の基盤 : 関連する複数のクラス間で共通の振る舞いや状態を共有する際に使用します。

implements (実装)

implements は、あるクラスが特定のインターフェース(契約)に従うことを意味します。

ここでの「契約」とは、「 こういうメソッドがあるべきだよ 」という約束だけを意味し、中身(処理の内容)は決まっていません。

class Flyable {
  void fly(); // メソッドだけ宣言(中身なし)
}

class Bird implements Flyable {
  @override
  void fly() {
    print("鳥が飛ぶ");
  }
}

void main() {
  Bird bird = Bird();
  bird.fly();
}

このように、Flyable は「 fly() メソッドがあること 」を約束しているだけで、どうやって飛ぶかは Bird クラスに任されています。

「どんなことをするか」は親(インターフェース)が決めてないから、子(実装)が自由に決めてOK!
やりたいようにやっていいんです🙌

多重実装 : 複数のインターフェースをimplementsすることができます。
振る舞いの強制 : インターフェースで定義されたすべてのメソッドを、実装するクラスで必ず定義(実装)しなければなりません。
契約の保証 : そのクラスが特定の機能や振る舞いを備えていることを保証します。

まとめ

FlutterやDartで開発していると、StatelessWidget や StatefulWidget を extends するケースや、インターフェース的に設計された抽象クラスを implements するケースがよくあります。

これらをうまく使い分けて、読みやすくて拡張しやすいコードを書いていきましょう💡

Discussion