Flutterにおいてextendsをよく見るので理解を深めたくこの記事を書きました。
extendsの使い方やimplementsとの違いを知りたい方はぜひご覧ください。
extentsとは
Flutterにおけるextendsとは
- クラスが別のクラスから継承していることを示すために使用されるキーワード
です。
extendsというとは日本語で拡張という意味です。
Cambridge英語辞書の記載
to add to something in order to make it bigger or longer
何かを大きくしたり長くしたりするために追加すること
公式には以下のような記載がありました。
Use
extendsto create a subclass, andsuperto refer to the superclass:
サブクラスを作成するには extends を使用し、スーパークラスを参照するには super を使用します。
superについての説明はここでは省略しますが、Dartでは、親クラス(superクラス)・子クラス(サブクラス)が存在し、親クラスのメソッドなどを継承して子クラスで使用するために”extends”を使用します。
簡単な例で言うと、
class Animal {
void makeSound() {
print ( "Animal sound" );
}
}
class Dog extends Animal {
void makeSound() {
print ( "Bark" );
}
}- Animalクラスが親クラス(superclass)
- Dogクラスが子クラス(subclass)
で、「DogクラスがAnimalクラスを継承した」ということになります。
Flutterにおいてどのように使用するか
実際にFlutterで使用する場合は以下のような用途で使用できます。
- 継承して新しいクラスを作成
- 親クラスのすべてのプロパティとメソッドを継承
- 新しいプロパティを追加し既存のものをオーバーライドする
extends 参考例
継承して新しいクラスを作成
class Animal {
}
class Dog extends Animal {
}Dogクラスが親クラスであるAnimalクラスを継承しています。
親クラスのすべてのプロパティとメソッドを継承
class Person {
String name;
Person(this.name);
void greet() {
print('こんにちは、$nameです');
}
}
class Student extends Person {
Student(String name) : super(name);
}
void main() {
Student student = Student('太郎');
print(student.name); // 太郎
student.greet(); // こんにちは、太郎です
}
親クラスであるPersonクラスのプロパティnameを継承して子クラスStudentで使用しています。
また、greetという関数についても親クラスから継承して使用することが可能です。
新しいプロパティを追加したり既存のものをオーバーライドする
class Student extends Person {
int grade; // 新しいプロパティ
Student(String name, this.grade) : super(name);
}
void main() {
Student student = Student('花子', 3);
print(student.name); // 花子(親から継承)
print(student.grade); // 3(子で追加)
}
子クラスであるStudentにgradeという新しいプロパティを追加することができます。
この場合だと、gradeという新しく追加したプロパティも親クラスであるPersonから継承したnameも使用できる。
class Animal {
void makeSound() {
print ( "Animal sound" );
}
}
class Dog extends Animal {
@override
void makeSound() {
print ( "Bark" );
}
}
親クラスであるAnimalからmakeSound関数を継承し、子クラスで独自にカスタムすることが可能になります。
@overrideをつけることで、子クラスのタイポなどの際にコンパイルエラーが発生するため、「この関数はオーバーライドするよ・上書きするよ」明示的にすることをDartでは推奨しています。
class Dog extends Animal {
@override
void makeSond() { // ← タイポでエラーに!
print("Bark");
}
}Implements
extendsとよく比較されるものでimplementsがあります。
impementsとは
implemnetsとは
- 他のクラスをインターフェイスとして使用するための宣言
です。
公式には以下のような記載がありました。
A class implements one or more interfaces by declaring them in an
implementsclause and then providing the APIs required by the interfaces.クラスは、implements 句でインターフェイスを宣言し、インターフェイスに必要な API を提供することで、1 つ以上のインターフェイスを実装します。
ここでいう「APIを提供する」というのは、メソッド名や引数の型など継承元から完全一致で実装することを示します。
つまり、implementsキーワードを使用したクラスのメソッドやプロパティを使用することができます。
(implementsしたクラスのメソッドは全て宣言する必要あり)
これでBというインターフェイス・中継役のクラスをAで使用することができます。
implementsの特徴としては、以下2つです。
- implementsで実装したクラスにはインターフェイスのメソッドを全て定義する必要あり
- クラスは複数implementsすることが可能
abstract class Repository {
Future<void> save();
}
class ApiRepository implements Repository {
@override
Future<void> save() async {}
}
class LocalRepository implements Repository {
@override
Future<void> save() async {}
}implementsする場合はインターフェイス(Repositoryクラス)の関数を全て定義する必要がある
ここではsaveメソッドをオーバーライドして別のクラスで使用している
class A implements B, C, D {}上記のように複数のインターフェイスをimplementsすることが可能なことも特徴の一つです。
extendsとimplementsの違い
extendsとimplementsの違いとしては、2つでメソッドの定義と複数クラス実装できるかどうかです。
■メソッドの定義
- extendsは必ず全てのメソッドを継承したクラスで実装しなくても良い
- implemtensは必ずimplenensしたクラスでインターフェイスのメソッドを定義する必要がある
/// extendsの場合
class Animal {
void eat() {
print('eat');
}
void sleep() {
print('sleep');
}
}
class Dog extends Animal {
// eat, sleep を書いていない
// でも OK(親の実装をそのまま使う)
}
void main() {
final dog = Dog();
dog.eat(); // eat
dog.sleep(); // sleep
}
/// implementsの場合
// ↓ これだとエラー
class BadDog implements Animal {
@override
void eat() {}
// sleep がない → コンパイルエラー
}
// 全てを必ず実装
class Dog implements Animal {
@override
void eat() {
print('dog eats');
}
@override
void sleep() {
print('dog sleeps');
}
}■複数クラスの実装
- extendsは複数のクラスを継承することはできない
- implemtensは複数のクラスをimplementsすることが可能
// exntendsの場合エラーに
class Animal {
void eat() {}
}
class Pet {
void play() {}
}
// Dartでは不可
class Dog extends Animal, Pet {}// implementsの場合、複数OK
class Dog implements Animal, Pet {
@override
void eat() {
print('eat');
}
@override
void play() {
print('play');
}
}最後に
Stateless Widget等何か作成した際に必ずでてくるextendsについて簡単にまとめました。implementsとの違いも知ることでより深く理解できたと思います。
こういった普段何気なく使っているがどういう意図のものか知らない部分についても理解を深めていきたいですね。
ではまた。



コメント