TOP(About this memo)) > 一覧(Dart) > クラス(拡張・実装)
Use extends to create a subclass, and super to refer to the superclass:
base class A {}
base class AA implements A{}// 同じライブラリ内であればimplementsできる
// class B extends A {} // error: base classの先祖はbase, final, sealed classのみ
base class B extends A {}
sealed class C extends B {}
// class E extends C {} // error: base classの先祖はbase, final, sealed classのみ
base class E extends C {}
base class EE implements C{}
sealed class F {}
class G extends F {}
interface class P {}
class Q extends P{}// 同じライブラリ内であればextendsできる
final class R {}
base class S extends R{}// 同じライブラリ内であればextendsできる
base class SS implements R{} // 同じライブラリ内であればimplementsできる。
// ライブラリ外
// class X extends F {} // error: sealed classはライブラリ外でextendsできない。
// class X implements F {} // error: sealed classはライブラリ外でimplementsできない。
//final class X implements A{} // error: base classはライブラリ外でimplementsできない。
final class XX extends A{}
class XXX extends G {} // sealed classの派生クラスはextendsできる
class XXXX implements G {}// sealed classの派生クラスはimplementsできる
// class Y extends P{} // error: interfaceはライブラリ外でextendsできない。
class Y implements P{}
class YY extends Q{} // interface classのサブクラスであればextendsできる。
// base class YY extends R{}// error: final はライブラリ外でextends/implementsできない。
base class Z extends S{}// final classのサブクラスであればextendsできる。
Every class implicitly defines an interface containing all the instance members of the class and of any interfaces it implements. If you want to create a class A that supports class B’s API without inheriting B’s implementation, class A should implement the B interface.
class A {
final String _v;
A(this._v);
String f() => _v;
}
class B implements A {
@override
String get _v => _v;
@override
String f() => '$_v $_v';
}
class A {
String f() => '';
}
abstract class B implements A {}
Extends is the typical OOP class inheritance. If class a extends class b all properties, variables, functions implemented in class b are also available in class a. Additionally you can override functions etc.
Implements can be used if you want to create your own implementation of another class or interface. When class a implements class b. All functions defined in class b must be implemented.
With is used to include Mixins. A mixin is a different type of structure, which can only be used with the keyword with.
Mixins are a way of reusing a class’s code in multiple class hierarchies.
abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin implements HitTestTarget {
// ...
}
Subclasses can override instance methods (including operators), getters, and setters
abstract class A {
void a() {
print('a called');
}
int b(int a);
int c(int a);
}
class B extends A {
@override
int a() {
// voidはオーバーライドによって型の設定が可能。
return 3;
}
// void以外の戻り値は上書きできない。
/*@override
String b(int a) {
return "aaa";
}*/
// 同じpositional parameterが必要
/*
@override
String b() {
return "aaa";
}*/
// optional parameterの追加は可能(optional positional parameter)
@override
int b(int a, [int a2 = 3]) {
return a;
}
// optional parameterの追加は可能(optional named parameter)
@override
int c(int a, {int? a2}) {
return a;
}
// 必須パラメータの追加はできない
/*@override
int c(int a, {required int a2}) {
return a;
}*/
}
void main() {
// final a = A(); // エラー。抽象クラスはインスタンス化ができない。
final b = B("test");
b.a();
b.a2();
}
abstract class A {
void a();// 抽象メソッド。
void a2() {
print("a2 call");
}
}
abstract class AX extends A {
// 抽象クラスのため、a()の実装は不要である。
void ax() {
print("ax call");
}
}
class B extends A {
final String _a;
B(this._a);
// a()を実装する必要がある。
@override
void a() {
print('a call: $_a');
}
}
class C implements A {
// 暗黙的に作成されるAのinterfaceを実装する。
// aもa2もオーバーライドする必要がある。
final String _a;
C(this._a);
@override
void a() {
print('a overrided call: $_a');
}
@override
void a2() {
print('a2 overrided call: $_a');
}
}
class D implements AX {
// aもa2もaxもオーバーライドする必要がある。
final String _a;
D(this._a);
@override
void a() {
print('a call: $_a');
}
@override
void a2() {
print('a2 call: $_a');
}
@override
void ax() {
print("ax call");
}
}
class E extends A implements AX {
// Dとの違いとして、a2はAで実装されているものを継承されているため、Eの実装は不要。
// aに関しては抽象メソッドのため実装する必要がある。
// Flutter の Listenable, ValueListenableのサブクラスでこのテクニック?が使われていた。
final String _a;
E(this._a);
@override
void a() {
print('a call: $_a');
}
@override
void ax() {
print("ax call");
}
}