Menu
Coddy logo textTech

super キーワード

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

superキーワードは、子クラスからその親クラスに直接アクセスできるようにします。すでにコンストラクタの中でsuper(name)として使用されているのを見たことがあると思いますが、他のコンテキストでも便利です。

親のコンストラクタを呼び出す必要がある場合、super は継承チェーンに沿って引数を渡します:

class Vehicle {
  String brand;
  int year;
  
  Vehicle(this.brand, this.year);
}

class Car extends Vehicle {
  int doors;
  
  Car(String brand, int year, this.doors) : super(brand, year);
}

superキーワードを使用すると、子クラス内から親のメソッドやプロパティにアクセスすることもできます。これは、親の振る舞いを自分自身の振る舞いと併せて使用したい場合に特に便利です。

class Animal {
  String name;
  
  Animal(this.name);
  
  void makeSound() {
    print('$name makes a sound');
  }
}

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void makeSound() {
    super.makeSound();  // 最初に親のメソッドを呼び出す
    print('$name says meow!');
  }
}

super.makeSound() を呼び出すと、親クラスのバージョンのメソッドを明示的に呼び出すことになります。super がないと、makeSound() の呼び出しは現在のクラスのメソッドを参照することになり、潜在的に無限再帰を引き起こす可能性があります。

super を、「親のバージョンを使って」と言っているものだと考えてください。それがコンストラクタ、メソッド、プロパティのいずれであっても同様です。

challenge icon

チャレンジ

簡単

super キーワードを使用して、子クラスが親クラスの振る舞いにアクセスし、それを拡張する方法を示すメッセージングシステムを構築しましょう。基本となるメッセージクラスを基に、異なるメッセージタイプの階層を作成します。

コードを2つのファイルに整理します:

  • message.dart: ここでメッセージクラスを定義します:
    • String senderString content を持つ Message クラス(親クラス)。これら2つの値を受け取るコンストラクタと、From [sender]: [content] と出力する display() メソッドを含めます。
    • Message を継承する UrgentMessage クラス。追加の String priority プロパティを持たせる必要があります。コンストラクタは sender、content、priority を受け取り、最初の2つを super を使用して親クラスに渡します。display() メソッドをオーバーライドし、最初に super.display() を使用して親クラスのバージョンを呼び出し、次に Priority: [priority] を次の行に出力するようにします。
  • main.dart: メッセージファイルをインポートし、コンストラクタとメソッドの両方で super がどのように機能するかを示します:
    • 'Alice' からの内容 'Hello there!' の通常の Message を作成します。
    • その display() メソッドを呼び出します。
    • 区切りのために空行を出力します。
    • 'Bob' からの内容 'Server is down!'、優先度 'HIGH'UrgentMessage を作成します。
    • その display() メソッドを呼び出します。

UrgentMessagesuper を2つの方法で使用していることに注目してください。1つはコンストラクタで親にデータを渡すため、もう1つはオーバーライドされたメソッドで独自の出力を追加する前に親の出力を取り込むためです。

期待される出力:

From Alice: Hello there!

From Bob: Server is down!
Priority: HIGH

チートシート

super キーワードは、子クラス内から親クラスへのアクセスを提供します。

子クラスのコンストラクタで super() を使用して、親のコンストラクタに引数を渡します。

class Vehicle {
  String brand;
  int year;
  
  Vehicle(this.brand, this.year);
}

class Car extends Vehicle {
  int doors;
  
  Car(String brand, int year, this.doors) : super(brand, year);
}

オーバーライドされたメソッド内から親のメソッドを呼び出すには、super を使用します。

class Animal {
  String name;
  
  Animal(this.name);
  
  void makeSound() {
    print('$name makes a sound');
  }
}

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void makeSound() {
    super.makeSound();  // 親のメソッドを最初に呼び出す
    print('$name says meow!');
  }
}

super を使用せずにメソッド名を直接呼び出すと、現在のクラスのバージョンが参照されるため、オーバーライドされたメソッド内で無限再帰が発生する可能性があります。

自分で試してみよう

import 'message.dart';

void main() {
  // TODO: 'Alice' から内容が 'Hello there!' の通常の Message を作成する
  
  // TODO: message に対して display() メソッドを呼び出す
  
  // TODO: 区切りのために空行を出力する
  
  // TODO: 'Bob' から内容が 'Server is down!' で優先度が 'HIGH' の UrgentMessage を作成する
  
  // TODO: urgent message に対して display() メソッドを呼び出す
}
quiz icon腕試し

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

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