最初の学期では、JavaやUMLを介して、カプセル化、データ隠蔽、モジュール性、継承などのOOPの概念を紹介しました。(Javaは私の最初のプログラミング言語です)
それらはいずれもOOPの概念ではありません。それらはすべてオブジェクト指向の外部に存在し、オブジェクト指向に依存せず、オブジェクト指向の前に発明されたものも多くあります。
あなたがいることを考えるのであれば、それは OOがすべてに約あるものです、そして、あなたの結論は正しいです:あなたは、手続き型言語でそれらのすべてを行うことができ、彼らはOOとは何の関係もないので。
たとえば、モジュール性に関する独創的な論文の1つは、システムをモジュールに分解する際に使用する基準についてです。そこにはオブジェクト指向に関する言及はありません。(それは1972年に書かれましたが、それまでにOOはすでに10年以上経っていますが、まだあいまいなニッチでした。)
一方でデータの抽象化はオブジェクト指向では重要であり、それはより多くのある結果、それは決定的な特徴であるよりも、OO(メッセージング)の主要な特徴の。また、データの抽象化にはさまざまな種類があることを覚えておくことが非常に重要です。今日使用されている2つの最も一般的な種類のデータ抽象化(「抽象化なし」を無視した場合、おそらく他の2つの組み合わせよりも多く使用されます)は、抽象データ型とオブジェクトです。だから、ただ、「カプセル化」「情報ハイディング」、および「データの抽象化」と言って、あなたはOOのみであることから、OOについては何も言わなかった1データの抽象化の形式、および2は、実際には根本的に異なっています:
- 抽象データ型では、抽象化のメカニズムは型システムです。実装を隠すのは型システムです。(型システムは必ずしも静的である必要はありません。)オブジェクトを使用すると、型を必要としない手続き型インターフェイスの背後に実装が隠されます。(たとえば、ECMAScriptで行われているように、クロージャーを使用して実装できます。)
- 抽象データ型では、異なるADTのインスタンスは相互にカプセル化されますが、同じ ADTのインスタンスは互いの表現とプライベート実装を検査してアクセスできます。オブジェクトは常にすべてからカプセル化されます。オブジェクト自体のみが、独自の表現を検査し、独自のプライベート実装にアクセスできます。他のオブジェクト、同じタイプの他のオブジェクト、同じクラスの他のインスタンス、同じプロトタイプを持つ他のオブジェクト、オブジェクトのクローンなど、それを行うことができるものはありません。なし。
ところで、これが意味することは、Javaではクラスはオブジェクト指向ではないということです。同じクラスの2つのインスタンスは、互いの表現とプライベート実装にアクセスできます。したがって、クラスのインスタンスはオブジェクトではなく、実際にはADTインスタンスです。Javaのinterface
S、しかし、ないオブジェクト指向のデータの抽象化を提供します。つまり、インターフェースのインスタンスのみがJavaのオブジェクトであり、クラスのインスタンスはそうではありません。
基本的に、型については、インターフェイスのみを使用できます。これは、メソッドとコンストラクターのパラメーター型、メソッドの戻り型、インスタンスフィールド、静的フィールド、ローカルフィールドのinstanceof
型、演算子またはキャスト演算子への引数、およびジェネリック型コンストラクターの型引数は常にインターフェイスでなければならないことを意味します。クラスは、new
演算子の直後でのみ使用でき、他の場所では使用できません。
たとえば、モジュール性のために、プログラムを、コードが別々のファイルに含まれる明確に定義されたタスクを実行する多くの小さなプログラムに分割することができます。これらのプログラムは、明確に定義された入力と出力を介して互いに対話します。カプセル化を実現するために、ファイルを保護(暗号化?)することができます。コードを再利用するために、新しいプログラムで必要になったときにいつでもこれらのファイルを呼び出すことができます。これは、OOPが何であるかをすべてキャプチャしないのですか、それとも非常に明白な何かを見逃していますか?
あなたが説明するのはオブジェクト指向です。
それは確かにオブジェクト指向について考える良い方法です。実際、OOの最初の発明者が念頭に置いていたのは、まさにそれです。(アラン・ケイはさらに一歩進んだ。彼は、ネットワークを介して互いにメッセージを送信する小さなコンピューターをたくさん構想した。)「プログラム」と呼ばれるものは通常「オブジェクト」と呼ばれ、「呼び出し」の代わりに「。
オブジェクト指向とは、メッセージング(別名動的ディスパッチ)に関するものです。「オブジェクト指向」という用語は、Smalltalkのプリンシパルデザイナーであるアラン・ケイ博士によって作られたもので、彼は次のように定義しています。
私にとってのOOPとは、メッセージング、ローカルの保持と状態プロセスの保護と隠蔽、およびすべてのものの極端な遅延バインディングのみを意味します。
それを分解しましょう:
- メッセージング(Smalltalkに慣れていない場合は、「仮想メソッドのディスパッチ」)
- 状態プロセスは
- すべてのものの極端な遅延バインディング
実装上、メッセージングはレイトバインドプロシージャコールであり、プロシージャコールがレイトバインドである場合、設計時に呼び出す内容を知ることができないため、状態の具体的な表現について仮定することはできません。したがって、実際にはメッセージングについてであり、レイトバインディングはメッセージングの実装であり、カプセル化はその結果です。
彼は後に「大きなアイデアは「メッセージング」である」ことを明確にし、「メッセージ指向」ではなく「オブジェクト指向」と呼んだことを後悔しています。「オブジェクト指向」という用語は重要ではないもの(オブジェクト)そして、何が本当に重要なのかをそらす(メッセージング):
Smalltalkはその構文やクラスライブラリだけでなく、クラスに関するものでもないことを皆に思い出させようと、最後のOOPSLAで苦労したことを思い出してください。私がずっと前にこのトピックの「オブジェクト」という用語を作り出したことを残念に思う。
大きなアイデアは「メッセージング」です。これがSmalltalk / Squeakの核心です(Xerox PARCフェーズでは決して完成しなかったものです)。日本人は、「間にある」を意味する小さな単語maを持っています。おそらく、最も近い英語の同等語は「インタースティシャル」です。優れた成長可能なシステムを作成するための鍵は、内部のプロパティや動作がどうあるべきかではなく、モジュールの通信方法を設計することです。インターネットを考えてみてください-生きるためには、(a)単一の標準を超えたさまざまな種類のアイデアと実現を許可する必要があり、(b)これらのアイデア間のさまざまな程度の安全な相互運用性を許可する必要があります。
(もちろん、今日、ほとんどの人はオブジェクトではなくクラスに焦点を合わせていますが、これはさらに間違っています。)
メタファーとメカニズムの両方として、メッセージングはオブジェクト指向の基本です。
誰かにメッセージを送信した場合、そのメッセージをどう処理するかはわかりません。唯一のあなたが観察できる事は、その応答です。メッセージを自分で処理したかどうか(オブジェクトにメソッドがあるかどうか)、メッセージを他の誰かに転送したかどうか(委任/プロキシ)、さらに理解したかどうかはわかりません。それがカプセル化のすべて、つまりオブジェクト指向のすべてです。期待どおりに応答する限り、プロキシを本物と区別することさえできません。
「メッセージング」のより「現代的な」用語は「動的メソッドディスパッチ」または「仮想メソッド呼び出し」ですが、それは比metaを失い、メカニズムに焦点を合わせます。
したがって、Alan Kayの定義を見るには2つの方法があります。それを単独で見ると、メッセージングは基本的にレイトバインドプロシージャコールであり、レイトバインディングはカプセル化を意味するため、#1と結論付けることができます。と#2は実際には冗長であり、OOはすべて遅延バインディングに関するものです。
しかし、彼は重要なことはメッセージングであると後で明らかにしたので、異なる角度からそれを見ることができます:メッセージングは遅れている。メッセージングが唯一可能な場合、#3は簡単に当てはまります。1つだけのものがあり、その事が遅延バインディングである場合、すべてのものは遅延バインディングです。また、メッセージングからカプセル化が続きます。
同様の点は、データ抽象化の理解、ウィリアムR.クックの再訪、および「オブジェクト」および「オブジェクト指向」の簡略化されたモダンな定義に対する彼の提案にもあります。
操作の動的なディスパッチは、オブジェクトの本質的な特性です。これは、呼び出される操作がオブジェクト自体の動的プロパティであることを意味します。操作を静的に識別することはできません。また、一般に、実行することを除いて、特定の要求に応じて実行される操作を正確に知る方法はありません。これは、常に動的にディスパッチされるファーストクラスの関数とまったく同じです。
Smalltalk-72では、オブジェクトすらありませんでした!解析、書き換え、および再ルーティングされたメッセージストリームのみがありました。最初に登場したのはメソッド(メッセージストリームを解析して再ルーティングする標準的な方法)、後に登場したオブジェクト(プライベートステートを共有するメソッドのグループ化)です。継承はずっと後になり、クラスは継承をサポートする方法としてのみ導入されました。Kayの研究グループが既にプロトタイプについて知っていたなら、そもそもクラスを導入したことはなかっただろう。
型とプログラミング言語の Benjamin Pierceは、オブジェクト指向の定義機能はオープン再帰であると主張しています。
Alan Kayによると、オブジェクト指向とはメッセージングに関するものです。William Cookによると、OOはすべて動的メソッドのディスパッチに関するものです(これは実際に同じことです)。Benjamin Pierceによれば、オブジェクト指向はすべてオープン再帰に関するものであり、これは基本的に自己参照が動的に解決されることを意味します(または少なくともそれを考える方法です)。つまり、メッセージングです。
ご覧のとおり、「OO」という用語を生み出した人はオブジェクトについてかなり形而上学的な見解を持ち、クックはかなり実用的な見解を持ち、ピアスは非常に厳密な数学的見解を持っています。しかし重要なことは、哲学者、プラグマティスト、理論家がすべて同意するということです!メッセージングは、OOの1つの柱です。期間。
ここでは継承については言及していないことに注意してください!OOには継承は必須ではありません。一般に、ほとんどのオブジェクト指向言語には実装の再利用の方法がありますが、必ずしも継承である必要はありません。たとえば、何らかの形式の委任も可能です。実際、オーランド条約では、委任は継承の代替として議論されており、異なる形式の委任と継承がオブジェクト指向言語の設計空間内の異なる設計ポイントにどのようにつながるかについて説明しています。(実際、Javaのような継承をサポートする言語でさえ、人々は実際にそれを避けるように教えられており、オブジェクト指向には不要であることを示していることに注意してください。)