Dartにおけるクラスとオブジェクト指向の詳細な解説

インスタンスとメンバーの操作

var point = Point(2, 2);
point.y = 3;
assert(point.y == 3);
double dist = point.distanceTo(const Point(4, 4));
point?.y = 4;

オブジェクト生成と定数化

var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});

var constantPoint = const ImmutablePoint(2, 2);
var sameConst = const ImmutablePoint(2, 2);
assert(identical(constantPoint, sameConst));

// 一貫した定数コンテキストでの定数省略
const data = {
  'coords': [ImmutablePoint(0, 0)],
  'offsets': [ImmutablePoint(1, 1), ImmutablePoint(-1, -1)],
};

実行時型の確認

print('Runtime Type: ${object.runtimeType}');

インスタンス変数とアクセス制御

class Position {
  double latitude;
  double longitude = 0.0;
}

void main() {
  var pos = Position();
  pos.latitude = 35.6895;
  assert(pos.longitude == 0.0);
}

コンストラクタの多様なパターン

class Coordinate {
  final double x, y;
  Coordinate(this.x, this.y);

  Coordinate.origin() : x = 0, y = 0;

  Coordinate.fromJson(Map<String, double> json)
      : x = json['x']!,
        y = json['y']!;

  Coordinate.withCheck(double x, double y)
      : assert(x >= 0),
        assert(y >= 0),
        x = x,
        y = y;

  Coordinate.onXAxis(double x) : this(x, 0);
}

ファクトリと不変オブジェクト

class LogEntry {
  final String message;
  static final Map<String, LogEntry> _cache = {};
  
  factory LogEntry.fromRaw(String msg) {
    return _cache.putIfAbsent(msg, () => LogEntry._internal(msg));
  }
  
  LogEntry._internal(this.message);
  final String message;
}

メソッド定義とプロパティ

class Location {
  double lat, lng;
  Location(this.lat, this.lng);

  double distanceTo(Location other) {
    final dLat = lat - other.lat;
    final dLng = lng - other.lng;
    return sqrt(dLat * dLat + dLng * dLng);
  }
}

class Box {
  double left, top, width, height;
  Box(this.left, this.top, this.width, this.height);
  
  double get right => left + width;
  set right(double val) => left = val - width;
}

抽象クラスとメソッド

abstract class Drawer {
  void draw();
}

class RasterDrawer implements Drawer {
  @override
  void draw() => print('Drawing raster');
}

隱黙的なインタフェース

class Author {
  final String _name;
  Author(this._name);
  String greet(String someone) => 'Hi $someone, I\'m $_name';
}

class GhostWriter implements Author {
  String greet(String someone) => 'Echoing: $someone';
}

継承とオーバーライド

class BaseDevice {
  void initialize() => print('Default init');
}

class SmartDevice extends BaseDevice {
  @override
  void initialize() {
    super.initialize();
    print('Extended features loaded');
  }
}

演算子の再定義

class Offset {
  final double dx, dy;
  Offset(this.dx, this.dy);
  
  Offset operator +(Offset o) => Offset(dx + o.dx, dy + o.dy);
  Offset operator -(Offset o) => Offset(dx - o.dx, dy - o.dy);
}

noSuchMethodのカスタマイズ

class DynamicDispatcher {
  @override
  noSuchMethod(Invocation invocation) {
    print('Requested: ${invocation.memberName} with ${invocation.positionalArguments.length} args');
  }
}

拡張メソッド

extension NumberParsing on String {
  int toInt() => int.parse(this);
}

void main() {
  final value = '123'.toInt();
  print(value);
}

列挙型の活用

enum ThemeMode { light, dark, system }

void applyTheme(ThemeMode mode) {
  switch (mode) {
    case ThemeMode.light: print('Light mode'); break;
    case ThemeMode.dark: print('Dark mode'); break;
    case ThemeMode.system: print('System default');
  }
}

assert(ThemeMode.dark.index == 1);
assert(ThemeMode.values.contains(ThemeMode.system));

ミキ 시네リューション(ミックスイン)

mixin SoundEmittable {
  void makeSound() => print('Sound emitted');
}

class Animal with SoundEmittable {}

class Dog extends Animal {
  @override
  void makeSound() => print('Woof!');
}

クラスレベルの状態管理

class SessionManager {
  static final Map<String, dynamic> _storage = {};
  
  static void store(String key, dynamic value) {
    _storage[key] = value;
  }
  
  static dynamic retrieve(String key) => _storage[key];
}

タグ: Dart OOP constructor factory mixin

6月30日 22:37 投稿