LoginSignup
0
0

Dartの継承と実装

Last updated at Posted at 2024-06-08

他の言語のように継承や実装などを利用しながら、クラスのメンバのアクセス可能なスコープを考えてみる

今北産業

  • Dartのprotectedの実現例
  • DartのFactoryパターン実装例
  • Dartの基本的な継承、実装

protectedなメンバ変数の実現

Dartにはprotectedは存在しないため、スコープをサブクラスに限定したメンバへのアクセスの実現には少し工夫が必要です

実装例 抽象クラスで宣言、実装を行う

super classで継承するクラス共通の処理を行いつつ、サブクラスでは独自の実装を行うような設計を行う時にはこのような手段が取れます。

.dart
abstract class UserRepository {
 User get _user;
 
 int userId() {
  return _user.id;
 }

 String name() {
  return _user.name;
 }
 
}

class HotelGuestUserRepository extends UserRepository {
 @override
 final User _user;

 String guestName() {
   return 'hotel guset ' + _user.name;
 }
 
 HotelGuestUserRepository({required user}): _user = user;
  
}

少し複雑なポリモーフィズムの実現 Factoryパターン

サブクラスもいくつかの系統に分かれていて、系統ごとに同じinterfaceを定義できる場合、Factoryパターンなどでカプセル化とポリモーフィズムを利用した設計をしたくなるかと思います。

実装例

.dart
abstract class UserRepository {
 User get _user; // ①
 
 int userId() {
  return _user.id;
 }

 String name() {
  return _user.name;
 }
 
}

abstract class GuestUserRepository implements UserRepository { // ②
  String guestName();
}

class HotelGuestUserRepository extends UserRepository implements GuestUserRepository {  // ③
 @override
 final User _user;

 @override
 String guestName() {
   return 'hotel guset ' + _user.name;
 }
 
 HotelGuestUserRepository({required user}): _user = user;
  
}

class GuestUserRepositoryFactory {
  static GuestUserRepository create({required User user}) {
    return HotelGuestUserRepository(user: user);
  }
}

void main() {
  var user = User(1, 'John Doe');
  GuestUserRepository guestRepo = GuestUserRepositoryFactory.create(user: user);
  print('Guest Name: ${guestRepo.guestName()}'); // ④ 出力: Guest Name: hotel guest John Doe 
  print('User ID: ${guestRepo.userId()}'); // ⑤ 出力: User ID: 1 
  print('Name: ${guestRepo.name()}'); // 出力: Name: John Doe
}

解説

① Userをprotectedのアクセススコープにしたいため、super classではprivateなgetterとして定義する
② Factoryの戻り値型として利用するため、UserRepositoryのinterfaceを実装する
③ super classを継承し、interface定義であるGuestUserRepositoryを実装する
④ ③の実装でGuestUserRepositoryのinterfaceを実装しているのでアクセス可能
⑤ ②の実装でUserRepositoryのinterfaceを実装しているのでアクセス可能

Dartの実装

DartのInterfaceは抽象クラスでも具象クラスを定義しても生成される

.dart
// 具象クラス
class User {
 String name;

 User(this.name);
}

// 継承に見えるが実装
class GuestUser implements User {
 @override
 String name; // 具象クラスのnameメンバ変数を実装

 GuestUser(this.name);
}

// 抽象クラス
abstract class User {
 int get id;
 String name;
}

// 継承ではなく実装
class GuestUser implements User {
 @override 
 int id; // 抽象クラスのid getterをproperty実装
 
 @override
 String name; // 抽象クラスのnameプロパティを実装

 GuestUser(this.id, this.name);
}

Dartの継承

.dart
class User {
 String name;

 User(this.name);
}

class GuestUser extends User {
 GuestUser(String name) : super(name); 
}
.dart
abstract class User {
  String name;
  int get id;

  User(this.name);
}

// 継承
class GuestUser extends User {
  GuestUser(this.id, String name) : super(name);

  @override
  int id; // idゲッターを実装
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0