🗂
【Dart】Objectクラスの基本
【Dart】Objectクラス
参考
- 公式サイト
-
Object class - dart:core library - Dart API
- The base class for all Dart objects.
-
Object class - dart:core library - Dart API
事前知識
-
Objectは
toString()
関数を持っている- 全てのオブジェクトは
toString()
関数を持っている
- 全てのオブジェクトは
-
Objectは
==
演算子を持っている
※同じオブジェクト(hashCodeが同じオブジェクト)かを判断する- 全てのオブジェクトは
==
演算子を持っている
- 全てのオブジェクトは
-
Objectは
hashCode
プロパティを持っている- 全てのオブジェクトは
hashCode
プロパティを持っている
- 全てのオブジェクトは
toString()
- 自作クラスからオブジェクトを作成した際に、変数名をprintすると以下のようになる
-
print('$monster');
はprint(monster);
でも同様
-
class Monster {
String name;
Monster(this.name);
}
void main() {
final monster = Monster('Slime');
print('$monster');
}
実行結果
Instance of 'Monster'
- 上記は自作クラスがすべてのクラスのスーパークラスであるObjectの
toString()
を持っているため可能- Stringが求められる際に、変数名のみで呼び出すと、自動的に
toString()
がcallされる - そのため、ヘタに
toString ()
をoverrideすると以下のように更新される
- Stringが求められる際に、変数名のみで呼び出すと、自動的に
class Monster {
String name;
Monster(this.name);
String toString () {
return 'TEST';
}
}
void main() {
final monster = Monster('Slime');
print('$monster');
}
実行結果
TEST
==
演算子
- デフォルトでは、同じオブジェクト(hashCodeが同じオブジェクト)を指す場合にtrueが返る
class Monster {
String name;
Monster(this.name);
}
void main() {
final monster1 = Monster('Slime');
final monster2 = monster1;
print(monster1.hashCode);
print(monster2.hashCode);
print(monster1 == monster2);
}
実行結果
150374362
150374362
true
- 以下の場合は、異なるオブジェクトを指すためfalseが返る
class Monster {
String name;
Monster(this.name);
}
void main() {
final monster1 = Monster('Slime');
final monster2 = Monster('Slime');
print(monster1.hashCode);
print(monster2.hashCode);
print(monster1 == monster2);
}
実行結果
68876054
549608535
false
-
上記を同じと判断したい場合は、
==
演算子をoverride- 方法
- identical関数を利用し、同じオブジェクト(hashCodeが同じオブジェクト)を指す場合trueを返す
- 次にMonsterクラスの場合は、どちらもMonsterクラス、かつname値が同じならばtrueを返す
class Monster { String name; Monster(this.name); bool operator ==(Object other) { if (identical(this, other)) { return true; } if (other is Monster) { return this.runtimeType == other.runtimeType && this.name == other.name; } else { return false; } } } void main() { final monster1 = Monster('Slime'); final monster2 = Monster('Slime'); print(monster1.hashCode); print(monster2.hashCode); print(monster1 == monster2); }
実行結果
787479825 1029272677 true
- 方法
-
hashCodeもoverride
- 通常のhashCodeは、演算子==の比較に影響を与えるオブジェクトの状態を表す単一の整数であり、オブジェクト毎にhashCodeが存在
-
int get hashCode => name.hashCode;
とoverrideすると、オブジェクト自体ではなく、name変数の値毎にhashCodeを存在させることが可能- ※この場合も、identical関数では本来のオブジェクトが異なるかの判断をする
class Monster {
String name;
Monster(this.name);
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (other is Monster) {
return this.runtimeType == other.runtimeType && this.name == other.name;
} else {
return false;
}
}
int get hashCode => name.hashCode;
}
void main() {
final monster1 = Monster('Slime');
final monster2 = Monster('Slime');
print(monster1.hashCode);
print(monster2.hashCode);
print(monster1 == monster2);
}
実行結果
272189256
272189256
true
- 上記から、単純にオブジェクトのnameが同じであれば、同一と判断すればいいだけの場合は以下に省略可能
- hashCodeをoverrideし、
monster1.hashCode == monster2.hashCode
で判断
- hashCodeをoverrideし、
class Monster {
String name;
Monster(this.name);
int get hashCode => name.hashCode;
}
void main() {
final monster1 = Monster('Slime');
final monster2 = Monster('Slime');
print(monster1.hashCode);
print(monster2.hashCode);
print(monster1 == monster2);
print(monster1.hashCode == monster2.hashCode);
}
実行結果
272189256
272189256
false
true
- 【備考】hashCodeをoverrideした場合にも、本来のオブジェクトのhashCodeを確認
-
identityHashCode()
を利用
-
class Monster {
String name;
Monster(this.name);
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (other is Monster) {
return this.runtimeType == other.runtimeType && this.name == other.name;
} else {
return false;
}
}
int get hashCode => name.hashCode;
}
void main() {
final monster1 = Monster('Slime');
final monster2 = Monster('Slime');
print('hashCode:' + monster1.hashCode.toString());
print('hashCode:' + monster2.hashCode.toString());
print('identityHashCode:' + identityHashCode(monster1).toString());
print('identityHashCode:' + identityHashCode(monster2).toString());
print(monster1 == monster2);
}
実行結果
hashCode:272189256
hashCode:272189256
identityHashCode:783211106
identityHashCode:841221886
true
【備考】Comparable
- 目的
-
Comparable<T>
のインターフェイスを利用することで、[オブジェクト1].compareTo([オブジェクト2])
の比較を可能とする
-
- 実装方法
- クラス名に
implements Comparable<Monster>
を付ける -
compareTo
関数をoverrideする
- クラス名に
class Monster implements Comparable<Monster> {
String name;
Monster(this.name);
int compareTo(Monster other) {
if (this.name.length < other.name.length) return -1;
if (this.name.length > other.name.length) return 1;
return 0; // equal
}
int get hashCode => name.hashCode;
}
void main() {
final monster1 = Monster('Slime');
final monster2 = Monster('XXXXXX');
final monster3 = Monster('XXXX');
final monster4 = Monster('XXXXX');
print(monster1.compareTo(monster2));
print(monster1.compareTo(monster3));
print(monster1.compareTo(monster4));
}
実行結果
-1
1
0
Discussion