最初に
オブジェクト指向に苦手意識のある方には、「オブジェクト指向に誤解がある」 or 「世の中に蔓延しているオブジェクト指向に対する誤解を信じすぎている」ように思うので、少し書いてみました。
オブジェクト指向 (OOP)
「データ(変数)と手続き(関数)をひとまとまり(オブジェクト)として扱う考え方」であり、それ以上でもそれ以下でもありません。
「オブジェクトで思考する」から「オブジェクト思考指向」なんです。
継承/多態性etcは、オブジェクト指向の本質ではなく、オプショナルな枝葉にすぎません。
オブジェクト指向プログラミング言語 (OOPL)
オブジェクト指向(OOP)に基づいて設計されたプログラミング言語です。
OOPLを利用すれば、基本、オブジェクト指向を強制できますが、オブジェクト指向でない書き方をすることも可能です。オブジェクト指向を完全に強制できるわけではありません。
OOPLを利用しただけでは、オブジェクト指向を(完全に)強制することはできません。
なので、OOPLを採用したプロジェクトでは、コーディング・ルールやコード・レビュー等を介して、おかしな(妥当でない)コードが入り込まないようにしています。
(OOPLを利用していても、手続き型的なコードに妥当性のあるケースは少ないもののあります。)
オブジェクト指向(OOP)=OOPL、OOPL=OOP、であるかのように語られることが多いですが、オブジェクト指向(OOP)=OOPLではありません。
OOPLでなくてもOOPは実践できます。
クラス(Class)ベースOOPL
オブジェクト指向に 継承/多態性etcの枝葉のくっついた言語です。
OOPLとイコール(等価)ではなく、OOPLの一種にすぎません。
OOPL=ClassベースOOPLであるかのように語られることは多いです。
クラス(Class)
データ(変数)と手続き(関数)をひとまとまりにした概念であり構造体です。
ClassベースOOPLでは、オブジェクトはClassをインスタンス化したモノを指し、Classはインスタンス化して初めて実体を得ます。
枝葉
継承/多態性etcについて、無理に理解しようとしたり、無理に活用しようとしたりする必要はありません。
最初はモヤっとでも理解できていれば御の字です。
OOPで作成されたライブラリ・フレームワークetcを(調べながら)利用するうちに自然と理解できるようになり、どのように活用すればよいのかもみえてきます。
継承
親から子に性質が受け継がれるように、親クラスから子クラスに性質(変数/関数)を受け継ぐ概念です。
多態性 (ポリモーフィズム)
親と子で性質を変えられる概念というかOOPLの機能です。
無理に活用する必要はありません。
利用できるor利用が必要な場合に利用すればよいです。
必要性が薄いのに利用すれば、読み解き難い(可読性の低い)クラスが出来上がります。
クラス(Class)ベース以外のOOPL
JavaScript (JS)
プロトタイプ・ベースのOOPLです。
オブジェクト・リテラルというオブジェクトを簡潔に記述するための記法が存在します。
ES2015(ES6)にて、後付けでclass記法が導入されています。
JavaScriptにおけるClassはシンタックス・シュガー(糖衣構文)です。
TypeScript (TS):
独立した言語ではなく、JSの開発用ラッパー?言語です。
動的型付け言語であるJSはエンジニアのレベルがバラツキやすい多人数の開発で採用するには難があるので、開発時には静的型付けの形で開発し、実行時にはコンパイラを通してJSの形で実行する(擬似的な静的型付)言語として、広く採用されています。
オブジェクト・リテラルのみorオブジェクト・リテラルとクロージャ(関数の一種)の組み合わせで、Classを利用しなくてもOOPを実践可能です。
手続き型言語でのOOP
オブジェクト指向(OOP)は、OOPLでないと利用できないモノではなく、OOPL以外の手続き型言語でも利用できます。
但し、オプショナルな機能のうち、継承/多態性 については、同等の機能を別の形で実現することになります。
C
構造体に関数ポインタをセットすればクラスを表現できます。
デザイン・パターン
GoFによるデザイン・パターンが有名です。
クラス設計のパターン集であり、定石です。
定石なので、知っておくと便利ですが、無理に適用するモノではありません。
デザイン・パターンがハマる場合にのみ適用するようにしてください。
デザイン・パターンがハマるようにクラス設計を歪めてはいけません。
オブジェクト指向設計
オブジェクト指向に基づいた(アプリetcの)システム設計の方法論です。
最初は、そんな方法論があることを知っていれば十分です、中身を知っている必要はありません。
必要になってから学んでも遅くはありません、というか、必要になってから学んだほうがよいです。
また、あくまで方法論にすぎないので、無理に開発しているシステムの設計/開発に適用する必要はありません。
オブジェクト指向 vs 関数型 ?
近年、関数型言語が見直されるようになったので、勘違いされがちですが、誕生は、手続き型言語 → 関数型言語→ オブジェクト指向言語 の順です。
関数型言語より先にオブジェクト指向言語が普及し、後に関数型言語が見直されて、今に至っています。
関数型言語は、書いたプログラムが書いた本人以外にとって難解(読み解きにくい)になりがちです。
関数型言語はオブジェクト指向言語を駆逐するモノではありません。
駆逐するモノなら、オブジェクト指向言語は誕生していないor誕生しても誰にも目を向けられなかった、はずです。
関数型言語には、オブジェクト指向言語とはまた違う良さがあります。
オブジェクト指向言語には、関数型言語にはない良さがあります。
近年、誕生したプログラミング言語の多く(Swift、Java、C# etc)は、OOPをメインの設計基盤としながらも、関数型言語etcの機能を取り入れ、マルチパラダイム言語化の方向に向かっています。
関数型はオブジェクト指向を補完し、オブジェクト指向は関数型を補完する、相互補完の関係にある、と考えておけば問題ないです。
...推敲中