👏

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

2022/12/11に公開約2,800字

はじめに

  • ある程度はプログラミングができるようになってきた
  • 普段何気なく使っているプログラミング言語や設計思想について深く学びたいなというモチベーションがでてきた
  • 手始めにオブジェクト指向から学んでみる

オブジェクトとは

オブジェクト指向について考える前に、そもそもオブジェクトとは何かについて知る必要がある

オブジェクトとは、属性と振る舞いを持つもののこと

  • 属性(attribute): 状態を表すもの
  • 振る舞い(method): 何をするかを表すもの

ex. 人間

  • 属性 → 身長、体重、性別 など
  • 振る舞い → 歩く、喋る、座る など

クラスとは

オブジェクトの説明をする際に欠かせないのがクラス
クラスとは、オブジェクトの設計図で、オブジェクトをインスタンス化する際に使われる

ex. 車

  • オブジェクト - 車
  • クラス - 車の設計図

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

以下の4つの概念を満たすものをオブジェクト指向プログラミング言語という

  • カプセル化
  • 継承
  • ポリモーフィズム
  • コンポジション

カプセル化

カプセル化とは、属性と振る舞いを同じ実体の中に同居させること

オブジェクト指向プログラミング以前の構造型プログラミングにはなかった概念

カプセル化では、受け渡す値が明確であれば、内部構造はクラスの使用者に見せるべきではないという思想がある
以下の2つの概念を用いて設計する

  • インタフェース
  • 実装

インタフェース

インタフェースとは、クラスの使用者がどのようにクラスを使うかを記述したもの

  • インタフェースとしてのメソッドはpublicであらわされる

実装

実装とは、ユーザに見せない内部的な実装のこと

  • 情報のやり取りはクラスインタフェースに通してだけに限定するべきという思想
  • 実装としてのメソッドはprivateであらわされる

ex. 平方を計算するSquareクラス

public class Square {
  private int squareValue;

  // インタフェース
  public int getSquare(int value) {
    squareValue = calcSquare(value);

    return squareValue;
  }

  // 実装
  private calcSquare(int value) {
    // ここの計算方法を変えてもSquareクラスの使用者には影響がない
    return value * value;
  }
}

ex. コンセントと発電所

  • インタフェース: コンセント
    • ユーザはコンセントに差すことで電気を得られることを知っているだけでよい
  • 実装: 電力発電所
    • 電気を生み出せるなら火力発電でも、原子力発電でもユーザには影響がない

継承

継承とは、他のクラスから共通の属性や振る舞いを抽出して、新しいクラスを生成できること

ex. 哺乳類

  • 親クラス
    • Mammalクラス
  • 子クラス
    • Dogクラス
    • Catクラス

抽象化のレベル

継承は便利だが、どれだけ抽象化が必要なのか見極めるのが難しいので言語によって抽象化できるレベルも異なってくる

例えば、Birdクラス(親)におけるPengineクラス(子)など、例外が発生してしまうことがままある

  • 単一継承: 親クラスは一つのみ
    • Java, Swift など
  • 多重継承: 複数の親クラスを許可
    • C++ など

ポリモーフィズム

ポリモーフィズムとは、継承した子クラスによって、同じメソッドでも異なる応答を返せること
ギリシャ語で、「多くの形態」

ex. Shapeを継承するCircleクラスとRectangleクラス

Shapeクラス(親)
public abstract class Shape {
  private double area;

  public abstract double getArea();
}
Circleクラス(子)
public class Circle extends Shape {
  double radius;

  public Circle(double r) {
    radius = r;
  }

  // 同じ名前のメソッド
  public double getArea() {
    return 3.14 * (radius * radius);
  }
}
Rectangleクラス(子)
public class Rectangle extends Shape {
  double length;
  double width;

  public Rectangle(double l, double w) {
    length = l;
    width = w;
  }

  // 同じ名前のメソッド
  public double getArea() {
    return length * width;
  }
}

CircleクラスとRectangleクラスをインスタンス化してgetArea()メソッドを呼ぶと異なった挙動をする

コンポジション

コンポジションとは、他のオブジェクトからオブジェクトを構成すること

ex. 車

車はエンジンやハンドルからなるが、エンジンは車を継承しているわけではなく、あくまで一部品

(マイクロサービス的な考え方?)

おわりに

  • 大学でもオブジェクト指向については勉強していたが、実務でガリガリとコードを書いてから改めて勉強してみると、得心のいくことが多くとても理解が深まった
  • 次はデザインパターンについての勉強をしていきたい

参考

https://www.amazon.co.jp/オブジェクト指向の考え方-5th-impress-top-gear/dp/4295010081

GitHubで編集を提案

Discussion

ログインするとコメントできます