実行時の型チェック
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 59/110。
ポリモーフィズム(多態性)により、オブジェクトをその親の型を通じて扱うことができますが、実行時にオブジェクトの実際の型を知る必要がある場合があります。これは実行時型チェックと呼ばれ、Dartはこの目的のために runtimeType プロパティを提供しています。
Dartのすべてのオブジェクトは、変数がどのように宣言されているかに関わらず、その実際の型を返すruntimeTypeプロパティを持っています:
class Animal {
void speak() => print('Some sound');
}
class Dog extends Animal {
@override
void speak() => print('Woof!');
}
void main() {
Animal myPet = Dog();
print(myPet.runtimeType); // 出力: Dog
}myPet は Animal として宣言されていますが、実際に作成されたオブジェクトは Dog であるため、その runtimeType は Dog になります。これは、オブジェクトの実際の型に基づいて判断を行う必要がある場合に役立ちます。
void describeAnimal(Animal animal) {
print('This animal is a ${animal.runtimeType}');
}
void main() {
var pets = [Dog(), Cat(), Dog()];
for (var pet in pets) {
describeAnimal(pet);
}
// 出力:
// This animal is a Dog
// This animal is a Cat
// This animal is a Dog
}runtimeTypeは正確な型を教えてくれますが、主にデバッグやロギングに役立ちます。次のレッスンでは、コード内で型をチェックしたり操作したりするための、より実用的な方法を提供するis演算子とas演算子について学びます。
チャレンジ
簡単runtimeType を使用して、さまざまな種類の車両を識別し、レポートする車両検査システムを構築しましょう。車両の階層構造を作成し、実行時に各車両の実際の型に関する情報を出力して検査する関数を作成します。
コードを2つのファイルに整理します:
vehicles.dart: ここで車両の階層を定義します:String modelプロパティとコンストラクタを持つVehicleクラス。[model] is startingと出力するstart()メソッドを含めます。Vehicleを継承し、追加のint doorsプロパティを持つCarクラス。Vehicleを継承し、追加のbool hasSidecarプロパティを持つMotorcycleクラス。Vehicleを継承し、追加のdouble cargoCapacityプロパティを持つTruckクラス。
Inspecting: [model]、2行目にType detected: [runtimeType]と出力し、最後にその車両のstart()メソッドを呼び出す関数inspectVehicle(Vehicle vehicle)を作成します。main.dart: 車両ファイルをインポートし、実行時の型チェックを実演します:- モデルが
'Sedan'でドアが4つのCar、モデルが'Sportbike'でサイドカーがfalseのMotorcycle、モデルが'Hauler'で積載量が5000.0のTruckを含むList<Vehicle>を作成します。 - リストをループし、各車両に対して
inspectVehicle()を呼び出します。 - 各検査の間に空行を出力します(ただし、最後の検査の後には出力しません)。
- モデルが
すべての車両が List<Vehicle> に格納されているにもかかわらず、runtimeType プロパティによって実際の型(Car、Motorcycle、または Truck)がどのように明らかになるかに注目してください。
期待される出力:
Inspecting: Sedan
Type detected: Car
Sedan is starting
Inspecting: Sportbike
Type detected: Motorcycle
Sportbike is starting
Inspecting: Hauler
Type detected: Truck
Hauler is starting自分で試してみよう
import 'vehicles.dart';
void main() {
// TODO: 以下を含む List<Vehicle> を作成してください:
// - モデルが 'Sedan' でドアが4つの Car
// - モデルが 'Sportbike' でサイドカーが false の Motorcycle
// - モデルが 'Hauler' で積載量が 5000.0 の Truck
// TODO: リストをループして、各車両に対して inspectVehicle() を呼び出してください
// 各点検の間に空行を出力することを忘れないでください(ただし、最後の点検の後には不要です)
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ自分で練習してみよう: Dartオンラインコンパイラ