【Dart】クラスの基本的な使い方
概要
Dartはオブジェクト指向言語でNull
(Objectの子孫)以外の全てのオブジェクトがクラスのインスタンスです。
その為、Dartを学ぶ上でとても大切なクラスについて使い方をざっくりまとめました。
※概念的な説明(クラスとは・インスタンスとは)はなく、Dartでクラスを使用するメモのようなものになっています。
クラスの宣言方法
class
キーワードの後に宣言したいクラス名を記載することで宣言できます。
下記に具体例を示しましたが、大枠このような構成になっています。
class クラスの名前 {
// インスタンス変数
// コンストラクタ
// インスタンスメソッド
}
下記が実際のDartのクラスの具体例です。
インスタンス変数の宣言方法がやや異なっていますが、それぞれコメントで補足しています。
- 全てのインスタンス変数は内部的にgetterを与えられます
- finalで宣言されていないインスタンス変数は同じくsetterも与えられます
class Person {
// インスタンス変数
int? age; // null許容型
final String name; // final変数
String address = '東京都'; // 初期値を設定
// コンストラクタ
Person(this.name);
// インスタンスメソッド
void introduce() {
print('私は$nameです');
}
}
(Named ・Factory・Redirecting)Constructors
Dartには幾つかの種類のコンストラクタが存在しているらしく、
下記の記事を見るとそれぞれの特徴、実際の使われ方がとても分かりやすく説明されていました🙇🙇
【Dart】簡単なユーザクラスを利用してNamed,Redirecting,Factoryコンストラクタ理解
インスタンス(オブジェクト)の作成方法・変数/関数のアクセス方法
クラス名とコンストラクタを使用することでインスタンスの作成が可能です。
上記で作成したPersonクラスのインスタンスを作成してみます。
void main() {
final taro = Person('太郎');
taro.age = 10;
taro.address = '京都府';
taro.introduce(); // => 私は太郎です。京都府に住んでいる10歳です。
}
継承
extends
キーワードを使用することでクラスを継承することができます
class Employee extends Person {
String department;
// superで親クラスのコンストラクタも呼んでいる
Employee(String name, this.department) : super(name);
}
親クラスのインスタンス変数・メソッドを上書き
@overide
キーワードを使用することで親クラスのインスタンス変数やメソッドを上書きすることが可能です。
class Employee extends Person {
String department;
Employee(String name, this.department) : super(name);
void introduce() {
print('私は$departmentに所属しています。');
}
}
下記が実行結果です
void main() {
final employee1 = Employee('花子', '営業');
employee1.introduce(); //私は営業に所属しています。
}
FlutterでステートレスなWidgetを作成する際に、StatelessWidgets
等を継承してbuild
メソッドをoverrideしますね。
class MyWidget extends StatelessWidget {
Widget build(BuildContext context) {
}
}
親クラスのインスタンス変数・メソッドを継承されたクラスで呼び出す
super
キーワードで親クラスのインスタンス変数やメソッドを呼び出すことが可能です。
class Employee extends Person {
String department;
Employee(String name, this.department) : super(name);
void introduce() {
super.introduce();
print('私は$departmentに所属しています。');
}
}
下記が実行結果になります。
void main() {
final employee1 = Employee('花子', '営業');
employee1.age = 25;
employee1.address = '東京都';
employee1.introduce();
// 私は花子です。東京都に住んでいる25歳です。
// 私は営業に所属しています。
}
Abstract(抽象)クラス
Abstract(抽象)クラスはインスタンス化することのできない継承されることを前提としたクラスです。
abstract
のキーワードをclassの前につけることで宣言が可能です。
abstract class Animal {
void walk();
}
class Dog extends Animal {
void walk() {
print('歩けるんだ僕は');
}
}
FlutterのStatelessWidgetもAbstractクラスですね。
参照: flutter/packages/flutter/lib/src/widgets/framework.dart
abstract class StatelessWidget extends Widget {
const StatelessWidget({ super.key });
StatelessElement createElement() => StatelessElement(this);
Widget build(BuildContext context);
}
Implicit Interfaces(暗黙的インターフェース)
DartではInterface
といったキーワードは存在しません。
多言語(Java等)のInterfaceのような役割を行うために、implements
キーワードを用います。
exntends
とは異なり、クラスに組み込むとそのクラス(暗黙的インターフェース)にあるメソッドや変数を全て実装(implement)する必要があります。
class Person {
final String name;
Person(this.name);
void introduce() {
print('私は$nameです。');
}
}
// Personの持つ全ての要素を実装(implement)してあげる必要がある
class Employee implements Person {
final String name;
String department;
Employee(this.name, this.department);
void introduce() {
print('私は$nameで、$departmentに所属しています。');
}
}
この辺の概念的な違い等は私の稚拙な説明より下記を読んで頂けると分かりやすいかと思います:bow:
- 【Dart】abstract,mixin,extends,implements,with等の使い方基礎
- "extends" versus "implements" versus "with"
- DART - DIFFERENCES BETWEEN EXTENDS, IMPLEMENTS AND MIXIN
Mixin
mixin
キーワードを使用することで拡張するメソッドや状態を定義することが可能です。
with
キーワードを使用することで実際に定義したmixinを使用することができます。
mixin Accounting {
void fileTaxies() {
print('あ、確定申告代わりにしときましたよ');
}
void askAccountant() {
print('税理士に聞いてみましょう.....');
}
}
class Person with Accounting {
final String name; // finalは初期化後に変更不可
Person(this.name);
}
実行結果は下記です
void main() {
final taro = Person('太郎');
taro.fileTaxies(); //あ、確定申告代わりにしときましたよ
}
実際にmixinが役に立つケースの説明等に関してはこちらがとても分かりやすかったです。
クラスメソッド・変数
static
キーワードを使用することでクラスメソッド・変数を定義することが可能です。
class Person {
static const initialAge = 0;
static void printFeature() {
print('足が2つ。腕も2つ。');
}
}
print(Person.initialAge) //=> 0
Person.printFeature() //=> '足が2つ。腕も2つ。'
参考
- A tour of the Dart languageのclassesを読みながら書いたのでそちらを見て頂くのが正確です。
- さらに細かい正確な情報はDart language specificationを見て頂ければと思います
Discussion