今回は、Dartが含まれる、オブジェクト指向言語の特徴について説明します。
はじめに
Dartは、JavaやC#と違い、1つのファイルの中で複数のモジュールを作成できます。
プライベートClass、変数
Javaと異なり、Dartではアクセス制限をつけるのにpublic、protected、privateなどのキーワードを使いません。Dartでは、名前の最初に_(アンダースコア)をつけることで、privateとなるのです。つまり、今までこのように書いていたのですが、
1 2 3 4 |
main(){ private String name; private String phone; } |
これではエラーが出てしまい、下のようにして使うということです。
1 2 3 4 |
main(){ String _name; String _phone; } |
コンストラクタ
デフォルトコンストラクタ
Dartでは、コンストラクタを定義しないと、自動でデフォルトコンストラクタが作成されます。
コンストラクタ構文のショートカット
インスタンス変数に値をセットするのに、「this.[インスタンス変数名]」という分を使うことができます。
1 2 3 4 5 6 7 8 9 10 11 |
class Name{ String firstName; String lastName; Name(this.firstName, this.lastName); } main(){ Name name = new Name('mark','smith'); print(name.firstName); print(name.lastName); } |
1 2 |
mark smith |
Newキーワード
Dartはコンストラクタを呼び出す際に、「New」キーワードは必要ありません。(使いたい場合は使うこともできます)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void main(){ Car car = Car('BMW','M3'); print(car.getBadge()); Car car2 = new Car('BMW','M3'); print(car2.getBadge()); } class Car{ String _make; String _model; Car(this._make, this._model){} String getBadge(){ return _make + '-' + _model; } } |
1 2 |
BMW-M3 BMW-M3 |
名前付きコンストラクタ
Dartでは、コンストラクタ名.[好きな名前]とすることで、複数のコンストラクタを定義することができます。Javaでいうオーバーロードの代わりとして使えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class ProcessingResult{ bool _error; String _errorMessage; ProcessingResult.success(){ _error = false; _errorMessage = ''; } ProcessingResult.failure(this._errorMessage){ //shortcut this._error = true; } String toString(){ return 'Error: ' + _error.toString() + ' Message: ' + _errorMessage; } } void main(){ print(ProcessingResult.success().toString()); print(ProcessingResult.failure('it broke').toString()); } |
1 2 |
Error: false Message: Error: true Message: it broke |
コンストラクタのパラメータ
コンストラクタは、メソッドと同様、異なる方のパラメータを持つことができます。
factoryコンストラクタ
新しいインスタンスを作らない可能性がある場合、factoryというキーワードを使うことができます。factoryは、最後に変数を返すことができます。以下に例を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Printer{ static final Printer _singleton = Printer._construct(); factory Printer(){ return _singleton; } Printer._construct(){ print('private constructor'); } PrintSomething(String text){ print(text); } } void main(){ Printer().PrintSomething("this"); Printer().PrintSomething("and"); Printer().PrintSomething("that"); } |
1 2 3 4 |
private constructor this and that |
インスタンス変数
アクセス制限を明示しない場合
変数の制限を明示しない場合、変数はpublicとして作成されます。
1 2 3 4 |
class Name{ String firstName; String lastName; } |
デフォルト値
変数のデフォルト値はnullです。
コンストラクタとメソッドのパラメータ
Flutterはコンストラクタやメソッドのパラメータについて、とても柔軟で、以下3つの種類があります。
- 必要
- あってもなくてもよい
- 名前付き
必要
まずは、パラメータが必要なものです。
1 2 3 4 5 |
class Car{ String _make; String _model; Car(this._make,this._model){} } |
あってもなくてもよい
次は、パラメータがあってもなくてもよいものです。これは、パラメータを[]で囲うことで明示します。
値を入れなかった場合はnullが入ります。
1 2 3 4 5 6 7 8 9 10 11 12 |
void main(){ Car car1 = Car("Nissan","350Z"); Car car2 = Car("Nissan"); } class Car{ String _make; String _model; Car(this._make,[this._model]){ print('${_make} ${_model}'); } } |
1 2 |
Nissan 350Z Nissan null |
名前付き
名前付きのパラメータはすべてあってもなくてもよいものです。これは、パラメータの最後に定義します。
これも、値が入れられなかった場合、nullが入ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void main(){ Car car1 = Car("Nissan",model:"350Z",color:"yellow"); Car car2 = Car("Nissan",color:"red"); Car car3 = Car("Nissan"); } class Car{ String make; String model; String color; Car(this.make,{this.model,this.color}){ print('${make} ${getOptional(model)} ${getOptional(color)}'); } String getOptional(String str){ return str == null?"" : ""+str; } } |
1 2 3 |
Nissan 350Z yellow Nissan red Nissan |
requiredデコレータ
「@required」をつけることで、名前付きパラメータを必須にすることができます。この機能は、DartではなくFrutterの機能であるため、Dartpadでは動きません。
インターフェイス
Dartは暗黙的インターフェイスを持ちます。
名前の通り、Dartではすべてのクラスは暗黙的にインターフェイスを持ち、それを公開しています。
他に
Method Cascades
Method Cascadesは、簡潔なコードを書くのに役立ちます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class Logger{ void log(dynamic v){ print(DateTime.now().toString() + ' ' + v); } } main(){ //method cascades 未使用 new Logger().log('program started'); new Logger().log('doing something'); new Logger().log('program finished'); //method cascades使用 new Logger() ..log('program started') ..log('doing something') ..log('program finished'); } |
1 2 3 4 5 6 |
2020-04-01 04:02:55.572 program started 2020-04-01 04:02:55.572 doing something 2020-04-01 04:02:55.572 program finished 2020-04-01 04:02:55.572 program started 2020-04-01 04:02:55.572 doing something 2020-04-01 04:02:55.577 program finished |