継承の基本
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 36/110。
継承は、クラスが別のクラスのプロパティやメソッドを引き継ぐことを可能にします。同じコードを書き直す代わりに、既存のクラスを基にした新しいクラスを作成します。元のクラスは親(またはスーパークラス)と呼ばれ、新しいクラスは子(またはサブクラス)と呼ばれます。
Dartでは、extendsキーワードを使用して親クラスから継承します:
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says woof!');
}
}
void main() {
var dog = Dog('Buddy');
dog.eat(); // Animalから継承
dog.bark(); // Dogで定義
}Dogクラスは、Animalのnameプロパティとeat()メソッドに自動的にアクセスでき、さらに独自のbark()メソッドも持っています。これにより「is-a」関係が作成されます。つまり、DogはAnimalであるということです。
子クラスは新しいプロパティやメソッドを追加できますが、親クラスからすべての公開メンバを継承します。プライベートメンバ(_ が付いたもの)は、異なるライブラリのサブクラスからは直接アクセスできないことに注意してください。ただし、継承されたオブジェクト内には依然として存在しています。
チャレンジ
簡単継承によって子クラスが親クラスの機能を再利用および拡張する方法を示す、乗り物システムを構築しましょう。一般的な乗り物のための親クラスと、特定の種類の乗り物のための子クラスを作成します。
コードを2つのファイルに整理します:
vehicle.dart: ここでクラスを定義します:Vehicleクラス(親クラス):String brandプロパティ、brandを受け取るコンストラクタ、および'$brand engine starting...'と出力するstart()メソッドを持ちます。Motorcycleクラス:Vehicleを継承します。追加のint ccプロパティ(排気量)を持ち、brandとccの両方を受け取るコンストラクタ(superを使用してbrandを親に渡す)を持ち、さらに'$brand is doing a wheelie!'と出力する独自のwheelie()メソッドを持ちます。
main.dart: vehicleファイルをインポートし、継承の動作を実演します:- brandが
'Toyota'のVehicleを作成します。 - その
start()メソッドを呼び出します。 - brandが
'Harley'でccが1200のMotorcycleを作成します。 - オートバイの
start()メソッド(Vehicleから継承)を呼び出します。 - オートバイの
wheelie()メソッド(Motorcycleで定義)を呼び出します。 - 子クラス独自のプロパティを示すために、
'Motorcycle engine: ${motorcycle.cc}cc'と出力します。
- brandが
Motorcycle クラスが Vehicle から brand プロパティと start() メソッドに自動的にアクセスできるようになり、同時に独自の cc プロパティと wheelie() メソッドを持っていることに注目してください。これが継承の力であり、既存のコードを基に構築していくことができます。
期待される出力:
Toyota engine starting...
Harley engine starting...
Harley is doing a wheelie!
Motorcycle engine: 1200ccチートシート
extendsキーワードを使用して、親クラスから継承する子クラスを作成します。
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says woof!');
}
}子クラスは、親クラスからすべての公開プロパティとメソッドを継承します。子クラスのコンストラクタでsuperを使用して、親クラスのコンストラクタにパラメータを渡します。
子クラスは、継承されたものにアクセスしながら、独自のプロパティやメソッドを追加できます。
var dog = Dog('Buddy');
dog.eat(); // Animalから継承
dog.bark(); // Dogで定義これにより「is-a」関係が作成されます。つまり、Dog(犬)はAnimal(動物)であるということです。
自分で試してみよう
import 'vehicle.dart';
void main() {
// TODO: ブランドが 'Toyota' の Vehicle を作成する
// TODO: vehicle の start() メソッドを呼び出す
// TODO: ブランドが 'Harley' で cc が 1200 の Motorcycle を作成する
// TODO: motorcycle の start() メソッド(Vehicle から継承)を呼び出す
// TODO: motorcycle の wheelie() メソッドを呼び出す
// TODO: motorcycle の cc プロパティを使用して 'Motorcycle engine: [cc]cc' を出力する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ