Menu
Coddy logo textTech

コンストラクタと継承

CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 41/110。

子クラスが親クラスを継承する場合、継承されたフィールドを適切に初期化するために、親のコンストラクタを呼び出す必要があります。Dartは、superを使用した初期化子リストを通じて、これを処理するための柔軟な方法を提供しています。

親クラスに引数付きのコンストラクタがある場合、子クラスはそれを明示的に呼び出す必要があります:

class Person {
  String name;
  int age;
  
  Person(this.name, this.age);
}

class Student extends Person {
  String school;
  
  Student(String name, int age, this.school) : super(name, age);
}

Dart 2.17 では、パラメータを親コンストラクタに直接渡すための、より簡潔な構文である super パラメータ が導入されました:

class Student extends Person {
  String school;
  
  // super.name と super.age は Person のコンストラクタに直接渡されます
  Student(super.name, super.age, this.school);
}

名前付きコンストラクタを使用する場合、どの親コンストラクタを呼び出すかを指定します。

class Employee extends Person {
  String department;
  
  Employee(super.name, super.age, this.department);
  
  Employee.intern(String name, this.department) : super(name, 18);
}

基本的なルールは単純です。子が独自のプロパティを追加する前に、親が完全に初期化されていなければなりません。従来の super() 呼び出しを使用する場合でも、新しいスーパーパラメータを使用する場合でも、Dart は継承チェーンが親から子へと適切に構築されることを保証します。

challenge icon

チャレンジ

簡単

継承においてコンストラクタがどのように機能するかを実証する、製品在庫システムを構築しましょう。異なる製品タイプがベースとなる製品クラスを継承し、それぞれが親コンストラクタを通じて適切に初期化される階層構造を作成します。

コードは2つのファイルに分けて構成します:

  • product.dart: ここで製品の階層を定義します:
    • String namedouble price プロパティ、両方の値を受け取るコンストラクタ、および [name]: $[price] を出力する info() メソッドを持つ Product クラス。
    • Product を継承し、String author プロパティを追加した Book クラス。スーパーパラメータを使用して、nameprice を親コンストラクタに転送します。
    • Product を継承し、int warranty プロパティ(月単位)を追加した Electronics クラス。初期化リスト内で伝統的な super() 呼び出しを使用して、親に値を渡します。
  • main.dart: 製品ファイルをインポートし、両方のコンストラクタ継承アプローチを実証します:
    • 名前が 'Dart Essentials'、価格が 29.99、著者が 'Jane Smith'Book を作成します。
    • その info() メソッドを呼び出し、次に Author: [author] を出力します。
    • 空行を出力します。
    • 名前が 'Wireless Mouse'、価格が 45.50、保証期間が 24Electronics を作成します。
    • その info() メソッドを呼び出し、次に Warranty: [warranty] months を出力します。

どちらの子クラスも、オーバーライドすることなく Product から info() メソッドを継承します。主な違いは親コンストラクタの呼び出し方法にあります。Book はよりクリーンなスーパーパラメータ構文を使用し、Electronics は初期化リストで super() を使用する伝統的なアプローチを使用します。

期待される出力:

Dart Essentials: $29.99
Author: Jane Smith

Wireless Mouse: $45.5
Warranty: 24 months

チートシート

子クラスが親クラスを継承する場合、継承されたフィールドを適切に初期化するために、親クラスのコンストラクタを呼び出す必要があります。

従来の方式 - 初期化子リストで親コンストラクタを明示的に呼び出す:

class Person {
  String name;
  int age;
  
  Person(this.name, this.age);
}

class Student extends Person {
  String school;
  
  Student(String name, int age, this.school) : super(name, age);
}

Superパラメータ (Dart 2.17+) - パラメータを親コンストラクタに直接渡す:

class Student extends Person {
  String school;
  
  Student(super.name, super.age, this.school);
}

名前付きコンストラクタ - 呼び出す親コンストラクタを指定する:

class Employee extends Person {
  String department;
  
  Employee(super.name, super.age, this.department);
  
  Employee.intern(String name, this.department) : super(name, 18);
}

自分で試してみよう

import 'product.dart';

void main() {
  // TODO: 以下の内容でBookを作成してください:
  // - name: 'Dart Essentials'
  // - price: 29.99
  // - author: 'Jane Smith'

  // TODO: bookのinfo()メソッドを呼び出してください

  // TODO: "Author: [author]" を出力してください

  // TODO: 空行を出力してください

  // TODO: 以下の内容でElectronicsを作成してください:
  // - name: 'Wireless Mouse'
  // - price: 45.50
  // - warranty: 24

  // TODO: electronicsのinfo()メソッドを呼び出してください

  // TODO: "Warranty: [warranty] months" を出力してください
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン