Flutter開発入門21 Dartで学ぶオブジェクト指向プログラミング(OOP)の基本

Flutter

はじめに

 オブジェクト指向プログラミング(OOP)は、現代の多くのプログラミング言語で採用されている重要な概念です。Dartも例外ではなく、クラスやオブジェクト、継承、カプセル化などのOOPの要素をしっかりサポートしています。本記事では、Dartでのオブジェクト指向プログラミングについて、基本から応用まで分かりやすく解説します。これをマスターすることで、クリーンで保守しやすいコードを書けるようになります。

オブジェクト指向プログラミングとは

 オブジェクト指向プログラミング(OOP)は、プログラムを「オブジェクト」という実体の集合として構築する方法です。各オブジェクトは、データ(プロパティ)と、そのデータを操作するメソッド(関数)を持ちます。OOPの基本原則として、「カプセル化」「継承」「ポリモーフィズム」「抽象化」の4つがあります。

  • カプセル化: データ(プロパティ)とそれを操作するメソッドを1つのオブジェクト(クラス)としてまとめること。
  • 継承: 既存のクラス(親クラス)の機能を別のクラス(子クラス)が引き継ぐこと。
  • ポリモーフィズム(多態性): 親クラスのメソッドを子クラスで上書き(オーバーライド)して、それぞれ異なる動作をさせること。
  • 抽象化: 必要な機能をクラスとして定義し、具体的な実装はサブクラスに任せること。

これらの概念を使うことで、コードの再利用性や保守性が向上し、規模の大きなプロジェクトでも効率的に開発が進められます。

Dartにおけるクラスとオブジェクト

 Dartは完全なオブジェクト指向言語で、すべてがオブジェクトとして扱われます。ここでは、クラスとオブジェクトの基本的な定義と使い方を見ていきましょう。

クラスの定義

 クラスは、オブジェクトを作成するための設計図です。クラスはプロパティ(データ)とメソッド(機能)を持つことができます。以下例となります。

class Car {
  // プロパティ
  String brand;
  String model;
  int year;

  // コンストラクタ
  Car(this.brand, this.model, this.year);

  // メソッド
  void drive() {
    print('The $year $brand $model is driving.');
  }
}

 この例では、Carクラスを定義しています。このクラスはbrand(車のブランド)、model(モデル)、year(製造年)という3つのプロパティと、drive()というメソッドを持っています。

オブジェクトの生成

 クラスからオブジェクト(インスタンス)を生成することができます。オブジェクトはクラスの実体であり、そのクラスのプロパティやメソッドを持っています。以下例となります。

void main() {
  // Carクラスのオブジェクトを生成
  Car myCar = Car('Toyota', 'Corolla', 2020);

  // オブジェクトのプロパティにアクセス
  print(myCar.brand);  // Toyota

  // メソッドの呼び出し
  myCar.drive();  // The 2020 Toyota Corolla is driving.
}

 ここでは、CarクラスからmyCarというオブジェクトを生成し、そのプロパティやメソッドにアクセスしています。

カプセル化

 カプセル化とは、データを隠蔽し、外部から直接アクセスできないようにすることです。通常、Dartではアンダースコア(_)をプロパティやメソッドの名前の前に付けることで、そのプロパティやメソッドをプライベートにできます。以下例となります。

class Person {
  String _name; // プライベートプロパティ

  Person(this._name);

  // ゲッター
  String get name => _name;

  // セッター
  set name(String newName) {
    _name = newName;
  }
}

 ここでは、_nameプロパティをプライベートにし、getsetを使って外部から安全にアクセスできるようにしています。

継承

 継承は、既存のクラス(親クラス)からプロパティやメソッドを引き継ぎ、新しいクラス(子クラス)を作成する仕組みです。これにより、既存のコードを再利用しつつ、新しい機能を追加することができます。

class Animal {
  void eat() {
    print('This animal is eating.');
  }
}

class Dog extends Animal {
  void bark() {
    print('The dog is barking.');
  }
}

 DogクラスはAnimalクラスを継承しており、eat()メソッドを引き継いでいます。Dogクラスには新たにbark()メソッドが追加されています。以下使い方の例となります。

void main() {
  Dog myDog = Dog();
  myDog.eat();  // Animalクラスのメソッドを利用
  myDog.bark(); // Dogクラス独自のメソッド
}

ポリモーフィズム(多態性)

 ポリモーフィズムは、同じインターフェースを持つ異なるクラスが、それぞれ異なる実装を行うことを指します。これにより、同じメソッド呼び出しが異なる動作をすることができます。

class Animal {
  void speak() {
    print('The animal makes a sound.');
  }
}

class Dog extends Animal {
  @override
  void speak() {
    print('The dog barks.');
  }
}

class Cat extends Animal {
  @override
  void speak() {
    print('The cat meows.');
  }
}

 ここでは、AnimalクラスにDogCatクラスが継承され、それぞれがspeak()メソッドを独自にオーバーライドしています。

void main() {
  Animal myDog = Dog();
  Animal myCat = Cat();

  myDog.speak(); // The dog barks.
  myCat.speak(); // The cat meows.
}

まとめ

 Dartのオブジェクト指向プログラミング(OOP)は、クラスやオブジェクト、カプセル化、継承、ポリモーフィズムといった概念に基づいており、これらをうまく使うことで、保守性と再利用性の高いコードを書くことができます。これらの基本原則を理解し、実際のアプリケーションに適用することで、FlutterやDartでの開発がより効果的で効率的になります。

コメント