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

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

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

オブジェクト指向パラダイムにおけるプログラミング.

以下の要素をそなえもつ.

現在オブジェクト指向言語と呼ばれているものは,実際には,

  • Abstruct Data Type (Java Integer 型)
  • オブジェクト (Java Object 型)

の 2 つを合わせもっている.

その意味で, オブジェクト指向言語と言うよりは抽象データ言語というほうが正しい.

データ抽象(Data Abstruction) #

データ抽象, Data Abstruction. Expression Problem における解決策.

3 つの構成要素がある.

  • Input
  • Output
  • Interface

データ抽象は内部と外部からなるプログラムかつ, 両者がインターフェースを通じてやりとりするもの.

A data abstraction is a part of a program that has an inside, an outside, and an interface in between The inside is hidden from the outside.

データを抽象的に使う, 使い方.実装にとらわれずにデータを使うこと. インタフェースと呼ばれる規則にしたがって使用される具体化の集合.

データ抽象を型 (Type) といって済ますこともある. 抽象データ型 (ADT) は, 特殊なデータ抽象. 値の集合と, それに関する操作の集合.(CPMCP p431)

以下のコンセプトに支えられている

  • High-order Programming (高階関数)
  • Static Scoping (クロージャ)
  • Explicit State (明示的状態)

Data Abstruction は 2 つの実現方法がある.

Input/Output #

内部は外部からは隠蔽されている. -> カプセル化という.

The inside is hidden from the outside

Interface #

The interface is a set of operations that an be used according to certain rules.

データ抽象には, 主に二つの方法がある.

  • Abstract Data Type (ADT) keeps values and operations separate.
  • Object groups together value and operations in a single entity.

Java インタフェースは, 階層を持たない型システムを構築する. (Effective Java p91 抽象クラスよりもインタフェースを選ぶ)

抽象クラスよりもインタフェースを選ぶ #

ref: Effective Java (p93)

実装の観点では,

  • 抽象クラスはメソッドに対する実装を含むことを許されている.
  • インタフェースはメソッドに対する実装を含むことを許されていない.

機能の観点では,

  • 抽象クラスはある機能の実装を強制する.
  • インタフェースは任意の機能を混ぜ合わせる.

階層化の観点では,

  • 抽象クラスは物事を階層化することに優れる.
  • インタフェースは階層を持たないものをまとめることに優れる.

インタフェースは, 階層を持たない型システムを構築する.

  • インタフェースは型を定義するために利用する
  • インタフェースは定数を提供するために使用しない
    • Enum を検討する
    • Util クラスを検討する
    • 関連するクラスのメンバを検討する

SICP における説明 #

データオブジェクトをどう表現するかに関するプログラムの部分を, データオブジェクトをどう使うかに関するプログラムから隔離する方法.(SICP)

constructor(構成子), selector(選択子) によって、どう使うかに関するプログラムの 抽象の壁 を構築し、抽象レイヤを構築する.

これを、Data Abstruction(データ抽象) という.

データによるレイヤー構造を構築することで複雑なシステムをうまく構築することができる.

抽象の壁という意味は、壁をつくることで、ある場所での変更を局所的なレイヤの変更に封じこめることができる.

カプセル化(Encapsulation) #

プログラムと内部と内部をインタフェースで分けること. カプセル化のメリットは大規模開発をシンプルにする.

  • 正しさを保証する.
  • 複雑さを解消する.

カプセル化とはあらゆるものを隠蔽すること #

カプセル化がデータ隠蔽というのは狭義の定義.

カプセル化とはあらゆるものを隠蔽すること.

  • データ
  • メソッド
  • 実装
  • 派生クラス
  • 設計の詳細
  • 実体化の規則
  • 型

流動的要素を探し出してカプセル化する

某元チーム先輩エンジニアの発言 #

ある目的をもったモノの集合(N 氏).モノには特性 (属性と操作) がある.

アプリケーションを設計するということは, まずそのアプリケーションで利用されるデータ型を定義するということからはじめる. (AplInteger, AplString みたいなもの). その後, 自分が定義したデータ型を操作するインタプリタを設計する.

実装では, Java をつかっているものの, Java はそれらの抽象データ型のインタプリタでしかない. 抽象データとインタプリタを設計することが設計.

Abstract Data Type #

OOP を語る上では理解をさけられない.

ref: Abstract data type: 抽象データ型(ADT)

オブジェクト(Object) #

値と操作をひとつのまとまりとしたもの. 以下の構成要素をもつ.

  • 値 ・・・ Explicite State (明示的状態 .. 時間とともに変化する値)
  • 操作 ・・・ Procedural Data Abstruction (手続的データ抽象)

メソッドと属性(Methods/Attributes) #

オブジェクトは内部と外部はインタフェースを通じてやりとりされる. 内部の明示的状態を Attributes (属性), インタフェースを Methods (メソッド) という.

たとえば, A1 を属性, M1 をメソッドという.

declare
local
   A1={NewCell 0}
in
   proc {M1 Hoge} end
end

これはクラスでもインスタンスでもないことに注意!!

クラス(Class) #

抽象データ型(ADT) からなるデータ構造.

メソッドと属性を定義する特別なシンタックスを Class という. 属性とメソッドはレコードデータ構造によって管理されているだけである!

Class とは, Pair ( attrs[属性の集合] : methods[メソッドの集合]) )

または, Java ならば, こうかいてもいい.

   HashMap<String, HashSet<String>> attrs = new HashMap<String, HashSet<String>>();
   HashMap<String, HashSet<String>> methods = new HashMap<String, HashSet<String>>();

   attrs.put ("Hoge", new HashSet (Arrays.asList ("attr1", "attr2")));
   methods.put ("Hoge", new HashSet (Arrays.asList ("method1", "method2")));

Class という概念によって, オブジェクトの"宣言"と"生成 (new)“を分離する.

クラスは, 継承・ポリモーフィズム・カプセル化などの, オブジェクト指向プログラミングにおける重要な概念を実現する強力な手段.

インスタンス化(Instantiation) #

オブジェクトは一つのメソッドで, 異なる属性をもつ複数のオブジェクトを生成できる. この能力を Instantiation (インスタンス化) という.

Procedure Dispatch #

オブジェクトは単一なエントリポイントをもつ. (エントリポイント = 呼び出し口) エントリポイントに渡される引数をメッセージという. 下の例だと, Counter がエントリポイント. エントリポイントに inc,get メッセージを送る.

   {Counter inc}
   {Counter get (X)}

エントリポイントから, メッセージに対応するプロシージャが呼びだされる.

メッセージとプロシージャはあらかじめ Dispatch (バンドリング) されている.

ポリモーフィズム #

各要素 (定数, 変数, 式, オブジェクト, 関数, メソッドなど) についてそれらが複数の型に属することを許すという性質.

詳細はこっち: 📝ポリモーフィズム

ポリモーフィズムはオブジェクト指向固有の概念ではない. 以下はOOの観点からポリモーフィズムを説明.

インタフェース: Interface #

抽象データ型のメソッド.

Object 型を分類し, 同じカテゴリに属するクラスに共通のインターフェイスを取り決める.

implements ステートメントは, クラスたちのカテゴリ分類を明確にする方法.

変数の型としてカテゴリクラスを指定すると, そのカテゴリを Implements したクラス (つまり, カテゴリに属するクラス) のインスタンスも格納できるようになる.

オブジェクトが共通のインターフェイスを実装している場合, 他のオブジェクトに置き換えることができる.

継承: Inheritance #

継承. あるオブジェクトが他のオブジェクトの特性を引き継ぐこと.

継承は単に特殊化と再利用を実現する手段ではない. オブジェクトを分類するための手段である.


どう分類するか? 2つの切り口がある.

  • 共通性: 時がたっても変わらないものを抽象クラスに
  • 可変性: 流動的要素を具象クラスに.

クラスの集合がもつすべての責務を真っ当するためにインタフェースを用意する.

機能追加と機能実装の違い #

  • 「機能追加」 (スーパークラスが持っていない機能をサブクラスで追加) を目的としたもの
  • 「機能実装」 (スーパークラスで定義したインタフェースをサブクラスで実装) を目的としたもの

ref: :Bridge パターン - デザインパターン入門 - IT 専科

オーバーライド: override #

オブジェクト指向プログラミングにおいてオーバーライド (override) とは, スーパークラスで定義されたメソッドをサブクラスで定義しなおし, 動作を上書きすること.

ref. オーバーライド - Wikipedia

オーバーライド vs オーバーロード #

オーバーライド: override vs Overload: オーバーロード

両者はタイヘン混同しやすい. とくにJavaで同じようなポリモーフィズムの実現方法として登場するので.

オーバーライドは継承に紐づく概念であり, さらにいえばオブジェクト指向に関わる. オーバーライドは アドホック多相 のオブジェクト指向における実現方法の呼び名.

委譲: Delegation #

委譲(Delegation). あるオブジェクトの操作を一部他のオブジェクトに代替させる手法.

  • 委譲を行うオブジェクトは委譲先オブジェクトへの参照を持つ
  • 必要に応じてその参照を切り替える事で動作にバリエーションを持たせる事ができる.
  • プラグイン機構

ref: 委譲 - Wikipedia

コンポジション | Composition #

新たなクラスに, 既存クラスのインスタンスを保持する.

has-a の関係 (not is-a)

Prefer Composition over inheritance (Effective Java).

コンポジションと移譲の比較 #

委譲の実現には多くの場合コンポジションを使用する. 委譲は「目的」であり, コンポジションはその「手段」.

ref: コンポジションとデリゲーション - とある技術メモブログ

継承と委譲の比較 #

メリット

  • Java の場合継承は一クラスしかできないが, 委譲なら複数可能.
  • 継承なら親クラスのメソッドが全て公開されてしまうが委譲なら必要なものだけ公開できる.

デメリット

  • 継承に比べてコードの記述量が多くなる.
  • 継承は何も書かなければ親クラスの機能が使える.
  • 委譲はメソッドの呼び出しを実装しなくてはならない.

ref: オブジェクト指向で. 継承の他に, 委譲といのが出てきますが. これは具

関連する Design Pattern #

  • Adapter
  • Proxy
  • Facade
  • State
  • Strategy
  • Decorator

手続き型とオブジェクト指向の違い #

ref: 📝手続き型プログラミング

機能分解 #

ある問題を小さな機能にブレークダウンすることで, その問題を構成する機能要素の洗い出しをすることを機能分解と呼ぶ.

構造化プログラミング的アプローチ #

(手続き的な) 機能を適切な順序で呼び出す「メイン」プログラムが必要になる.

メインプログラムにはすべてを正しく動作させる, すなわち機能の組み合わせと呼び出し順序を制御するあまりに大きな責任が課せられる.

結果的にソースコードは複雑になる.

オブジェクト指向的アプローチ #

部分機能に対してそれ自体の振舞いに関する責任を持たせ, 実行指示を行うだけであと任せておく. これが委譲 (delegation) という考え方.

Mixin #

他のクラスから使用されるメソッド群を持つクラスが、他のクラスのスーパークラスにならないで済むための、特別な多重継承関係を実現するためのメカニズム.

ref. Mixin - Wikipedia

Is-a/has-a関係 #

Is-a は 継承関係. Has-a は 包含関係 (委譲)

Is-a 信仰. なんでも継承すればいいという考え方.

References #

ref. 💻essay: Rees by Jonathan Rees


ものすごくよい記事.歴史が端的にまとまっている.

Books #

Active Recalls #

オーバーライドとオーバーロードの共通点と違いはなんですか? #

どちらもオブジェクト指向におけるポリモーフィズムの実現手段.

オーバーライドは継承に関わり, 親クラスのメソッドを小クラスが上書きすること. オーバーロードは多重定義とも呼ばれて名前が同じ引数のことなるメソッドを定義できること.