Dartにおけるインターフェースの扱いを、swiftとの相違点からまとめてみました。
get/setについては既知であるとします。
インターフェースってなに?
まず、インターフェース(Interface) とは、オブジェクト指向型プログラミングによって認められた具体的な実装を持たない抽象型のことです。
swiftではprotocolキーワードを用いて実装されます。
// Buildingプロトコルの定義
protocol Building {
var height: Double { get }
var area: Double { get }
func volume() -> Double
}
// Buildingプロトコルに準拠したHouseクラス
class House: Building {
let height: Double
let area: Double
init(height: Double, area: Double) {
self.height = height
self.area = area
}
func volume() -> Double {
return height * area
}
}
例えば、ここでHouseクラス
で定義されている定数area
の宣言部分を削除してみましょう。
すると、次のようなエラーメッセージが表示されます。
Type 'House' does not conform to protocol 'Building'
インターフェース内(swiftではプロトコル内)に定義されたものは、そのインターフェースを準拠した型の中で実装が必須となることがわかります。
Dartにおけるインターフェース
次にDartではインターフェースがどのように実装されるかを確認します。
公式ドキュメントを確認すると、次のような記述が見つかります。
Dart has no interface keyword. Instead, all classes implicitly define an interface. Therefore, you can implement any class.
翻訳すると、Dart言語にはinterfaceキーワード(swiftでいうprotocol)が存在しない代わりに、全ての型において暗黙的なインターフェースが定義されているとのことです。
公式ドキュメントが紹介しているプログラム例を元に確認してみましょう。
class Person {
// interfaceが存在している
final String _name;
String greet(String who) => 'こんにちは、$who。私は$nameです。';
// コンストラクタにはinterfaceは存在していない
Person(this._name);
}
class Impostor implements Person {
String get _name => '';
String greet(String who) => 'こんにちは、$who。私が誰だか知っていますか?';
}
implements
があるクラス(インターフェース)を準拠していることを表すものです。
Personクラス
において定義されているfinal変数 _name
とgreet関数
は、インターフェースの観点に基づき、Impostorクラス
において再度定義され直さなければなりません。
では一般に、swiftでのprotocolキーワードのような表現をDartでするにはどうしたら良いのでしょうか?
abstractキーワード
abstractキーワードとは、抽象型を作成する際にDartで用いられるものです。
Dartにおける実装例を確認してみましょう。
abstract class Building {
final double height;
final double area;
Building({required this.height, required this.area});
double? volume() {}
}
class House implements Building {
final double height;
final double area;
House({required this.height, required this.area});
double volume() {
return this.height * this.area;
}
}
void main() {
final House house = House(height: 100, area: 100);
print(house.volume());
}
Buildingクラス
にabstractキーワードを付与することで、swiftのように抽象型のインターフェースとして扱うことができるようになりました。