複数のインターフェース
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 48/110。
継承に対するインターフェースの最大の利点の1つは、クラスが複数のインターフェースを実装できることです。Dartでは1つのクラスしか継承できませんが、インターフェースは必要な数だけ実装することができます。
abstract class Printable {
void printContent();
}
abstract class Saveable {
void save();
}
abstract class Shareable {
void share(String recipient);
}
class Document implements Printable, Saveable, Shareable {
String content;
Document(this.content);
@override
void printContent() {
print('Printing: $content');
}
@override
void save() {
print('Saving document...');
}
@override
void share(String recipient) {
print('Sharing with $recipient');
}
}複数のインターフェースを実装する場合、すべてのインターフェースのすべてのメソッドに対して実装を提供する必要があります。クラスは、サポートすることを約束したすべての契約を満たさなければなりません。
extends と複数の implements を組み合わせることもできます:
class Report extends Document implements Printable, Shareable {
Report(String content) : super(content);
// すべてのインターフェースメソッドを実装する必要があります
// (この場合はすでに Document から継承されています)
}この柔軟性により、複数の役割に適合するクラスを設計できます。SmartPhone は Camera、Phone、および MusicPlayer インターフェースを実装でき、各インターフェースが要求するすべての機能を実行できることを保証しつつ、独自の実装を保持できます。
チャレンジ
簡単1つのクラスが複数のインターフェースを実装して、異なる機能を組み合わせる方法を示すスマートデバイスシステムを構築しましょう。デバイスの機能ごとに個別のインターフェースクラスを作成し、それらすべてを実行できるデバイスを構築します。
コードを2つのファイルに整理します:
devices.dart: ここでインターフェースと実装クラスを定義します:Connecting to network...と出力するconnect()メソッドを持つConnectableクラス。Charging battery...と出力するcharge()メソッドを持つChargeableクラス。Displaying: [content]と出力するshowScreen(String content)メソッドを持つDisplayableクラス。Connectable、Chargeable、Displayableの3つのインターフェースすべてを実装するTabletクラス。コンストラクタとともにString brandプロパティを追加してください。実装では、connectに対して[brand] tablet connecting to WiFi、chargeに対して[brand] tablet charging via USB-C、showScreenに対して[brand] screen: [content]と出力するようにします。
main.dart: devicesファイルをインポートし、Tabletが3つのインターフェース契約すべてをどのように満たしているかを示します:- ブランドを
'Galaxy'としてTabletを作成します。 connect()を呼び出します。charge()を呼び出します。showScreen('Welcome Home')を呼び出します。
- ブランドを
Tablet クラスは、3つのインターフェースすべてのすべてのメソッドに対して独自の実装を提供する必要があります。これにより、複数のインターフェースを実装することで、各実装をデバイス固有に保ちながら、1つのクラスが複数の機能を約束できることがわかります。
期待される出力:
Galaxy tablet connecting to WiFi
Galaxy tablet charging via USB-C
Galaxy screen: Welcome Homeチートシート
クラスは、implements キーワードの後にカンマで区切って記述することで、複数のインターフェースを実装できます。
abstract class Printable {
void printContent();
}
abstract class Saveable {
void save();
}
class Document implements Printable, Saveable {
@override
void printContent() {
print('Printing...');
}
@override
void save() {
print('Saving...');
}
}複数のインターフェースを実装する場合、すべてのインターフェースのすべてのメソッドに対して実装を提供する必要があります。
extends と複数の implements を組み合わせることができます。
class Report extends Document implements Printable, Shareable {
Report(String content) : super(content);
// すべてのインターフェースメソッドを実装する必要があります
}これにより、クラスは複数の規約を満たし、同時に複数の役割を果たすことができます。
自分で試してみよう
import 'devices.dart';
void main() {
// TODO: ブランド 'Galaxy' で Tablet を作成する
// TODO: connect() を呼び出す
// TODO: charge() を呼び出す
// TODO: showScreen('Welcome Home') を呼び出す
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ