オブジェクト指向に必要な機能は何ですか?


9

言語またはライブラリが「オブジェクト指向」として定義されるために、言語またはライブラリが提供しなければならない機能とは正確には何なのかと思います。オブジェクト指向は、缶は、多かれ少なかれ、中に達成されることを何かである任意のまともな機能を備えた汎用プログラミング言語?それとも、オブジェクト指向プログラミングをサポートしていることを具体的に宣伝している言語でのみ達成できるものですか?

たとえば、次のCコードを見てください。

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE);
SDL_FreeSurface( screen );

またはここで説明したコード。

さて、上記のコードは継承、ランタイムポリモーフィズム(?)、仮想関数などを使用していません。しかし、私にはほとんどOOPのようです。

オブジェクト指向は、オブジェクト、クラス、構造体など、プログラミング言語またはライブラリによって提供される特別なパターンや機能を必要としない、作成および破壊可能なデータ構造に基づくコードを単に記述しているのですか?


2
OOPには通常、オブジェクトが必要です。ただし、ほとんどの言語でOOPのように見えるコードを書くことは可能です(「このアセンブリはOOPのように見える」とは言えないでしょう)
Raynos

上記のコードはifステートメントまたはループを使用していません。乗算や加算は使用しません。2行のコードと示されていないもののリストを使用して、判断を下すことはできません。この2行のコードから、オブジェクト指向言語ではなく、厳密にレイジーな関数型プログラミング言語であると推測できます。一般化の一部として2行のコードを使用することは、実際の問題ではありません。
S.Lott、2012年

リンクはまた、中に含まれる上記のコード私は時と判断しました。また、それはないことに注意判決、私はよ尋ねるこれはOOPと考えられるかどうかを。
ApprenticeHacker 2012年

ささいな答えはイエスです。私のポイントはこれです。コード例から、OOPについて判断することはできません。些細な定義です。言語がOOP言語として定義されているか、そうではありません。特定のコードサンプルではすべてのOOP機能が必要なわけでありません。実際、OOPコードで使用できる機能はごくわずかです。たとえば、Pythonでは1+2実際にはオブジェクト指向です。これは、2つの既存のオブジェクトから新しいオブジェクトを構築するコンストラクタです。コードサンプルを使用しても何もわかりません。
S.Lott、2012年

この定義を使用してそれを言語と比較することの何が問題になっていますか(2つのコードサンプルではありません)? en.wikipedia.org/wiki/...
S.Lott

回答:


11

「オブジェクト指向」という用語を発明したアラン・ケイによれば、

私にとってのOOPは、メッセージング、ローカルでの保持と状態プロセスの保護と非表示、およびすべてのものの極端な遅延バインディングのみを意味します。SmalltalkとLISPで実行できます。これが可能な他のシステムがあるかもしれませんが、私はそれらを知りません。

(Smalltalkで実装されている)メッセージングは、ポリモーフィズムに匹敵する概念ですが、かなり強力です(少なくともC ++またはJavaでサポートされているポリモーフィズムの種類よりも)。これはすべての言語で実行できますが、その言語で直接サポートされていない場合はかなり苦痛です。基本的には、オブジェクトが何かを含む他のメッセージを送信できることを意味します。amdは、受信したメッセージに応じて反応します。メッセージングを完全にサポートするには、オブジェクトがソースコードで列挙せずにメッセージに柔軟に対応できる方法が必要です(これは基本的にメソッド/関数定義が行うことです)。

ローカルでの保持と状態プロセスの保護および非表示(別名:カプセル化)は、すべての言語で慣例に従って行うことができますが、それは多少不正行為です。言語レベルでのローカル保持は、実際には、オブジェクト指向であると主張するすべての言語(および共有しないものの多く)が共有する1つの機能のようです。通常、複数のインスタンスを持つ複合データ型を作成する方法があります。一方、保護と非表示は多くの場合、慣例によってのみ行われます。

すべてのものの遅延バインディング -CがKayのビジョンから本当に遠くにあるスライディングスケール(C ++と同様に、Javaははるかに近い)。偽装することもできます(COMを参照)が、使用するのは面倒です。

ケイが継承に言及していないことに注意してください。同じメールで彼は書いた

Simula IまたはSimula 67が継承を行う方法が好きではありませんでした(ただし、NygaardとDahlは途方もない思想家とデザイナーであると思っていました)。そのため、理解を深めるまで、継承を組み込み機能として除外することにしました。


4
JavaとC#はC ++よりも遅延バインディングにどのように近いのでしょうか?
fredoverflow 2012年

@FredOverflow:Javaは、最初に使用されたときに実行時にクラス定義を遅延ロードし、新しいクラスを簡単に追加したり、その場で生成したりできる非常に柔軟なメカニズムを介して暗黙的にロードします。C ++では、実行可能ファイルを再リンクするか、ライブラリを明示的にロードする必要があります。C#の状況は私が思ったほど明確ではないようなので、tiへの参照を削除しました。
Michael Borgwardt 2012年

5

オブジェクト指向プログラミングは構文機能ではなく、コーディングと設計の哲学です。その核となるのは、オブジェクトの概念です。これは、状態をグループ化して、それに作用するルーチン(または、見方によってはメッセージへの応答)をグループ化する構造です。OOPのもう1つの重要な側面はカプセル化です。実装の詳細を不透明な構造にラップし、明確に定義されたインターフェイスを介してそれらを接続します。OOP理論の他のほとんどすべては、これらの2つの基本に戻ります。

したがって、何らかの方法でオブジェクト(データとコードの両方を含むエンティティ)とカプセル化をモデル化できる任意の言語を使用してOOPを実行できます。たとえば、Cでは、関数ポインターを使用して構造体に関数を格納でき、ヘッダー/ソースファイルシステムを使用してカプセル化を実現できます。便利ではありませんが、OOPを行うには十分です。おそらくHaskellやMLのようなものを曲げてOOPを実行することもできますが、誰かがアセンブリでOOPを実行する方法を考え出しても驚くことはありません。

しかし実際には、明示的なオブジェクト指向プログラミングのための構文機能の完全なセットを提供する言語は、「オブジェクト指向」と呼ぶことができます。通常、これは、そのような言語が以下を備えている必要があることを意味します。

したがって、OOPの原則に準拠し、利用可能なOOP構文を使用する場合は、コードの一部をオブジェクト指向と呼びます。

ちなみに、Cの構文では明確ではありませんが、コード例で多態性と仮想関数を使用しています。私はSDLの専門家ではありませんがSDL_surface、それぞれが固有の実装セットを持つさまざまな異なるタイプのサーフェスを表現できると期待しています-メモリビットマップに何かをブリットし、スクリーンサーフェスにブリットすると、根本的に異なるものが必要になりますコード、しかしインターフェイス(SDL_surface*引数として取る関数)は同じままです。それと同じように、カプセル化も実装します。サーフェスの基になる表現に直接アクセスすることはできません。それだけで、の処理方法を知っている関数をSDL_surface実行する必要があります。これは、CでOOPを実行する方法の良い例です。


抽象データ型、データモデリング、およびカプセル化は、OOに固有のものではありません(簡単に説明します)。私は、OOをよりユニークな機能(メソッド呼び出しの動的バインディング、前述のメソッド呼び出しによる多態性など)に基づいて説明したいと思います
hugomg

4

私のOOについての理解は、OOは考え方であり、1つのワーカー(オブジェクト)または個々のワーカー(オブジェクト)のコラボレーションによって、それらのワーカー間でメッセージの受け渡しを介して計算タスクを達成できるという考えに基づく実装であるということです。オブジェクト)実行時。この実行時の動作には、それを有効にするための静的で動的な構造が必要です。

OOを実装するための特定の構文は、言語がOOかどうかを決定するキーではありません。たとえば、SmalltalkとC#の構文は異なりますが、どちらもOO言語です(程度は異なります)。重要なのは、与えられた言語が哲学(上記)を維持し、必要な埋め込み手段を提供するかどうかです。


2

学生時代、オブジェクト指向プログラミングは3つの柱に基づいていると教えられました。

  • カプセル化
  • 多型、および
  • 継承

オブジェクト指向言語と見なされるために、言語がこれらの機能サポートする必要があります。

これは、構文ではなく、一連の機能を説明していることに注意してください。したがって、あなたが書く必要があるかどうか

type obj; // or type obj = new type;
obj.func(arg);

または

type* ptr = create_type();
func(ptr, arg); 

関係ありません。

したがって、Cのオブジェクト指向パラダイムに従って実際にプログラムを作成できます。しかし、この言語はこれをサポートしていないため、かなり苦痛な作業になります。これが、Cがオブジェクト指向言語と見なされない理由です。


2
これらの「柱」を教えることは、おそらく世界に良いことよりも多くの害を及ぼしています。カプセル化は良いですが、それだけです。
tdammers 2012年

1
彼らは広く受け入れられているように見えるので、彼らは、このリストにいる: en.wikipedia.org/wiki/...
S.Lott

ポリモーフィズムと継承が悪い理由を説明できますか?
MathAttack 2012年

@MathAttack:私と話してるの私は確かにそう言っていなかったので。
sbi 2012年

1
@missingno:パラダイムを区別するために重要であると見なされるために、何かが特定のパラダイムに固有である必要はありません。関数は構造化プログラミングに固有である必要があるため、カプセル化はOOPに固有である必要はありません。
sbi

2

あなたはできる任意のまともな汎用言語でオブジェクト指向を行います。

それはだ簡単に使用可能な慣用的な構造を持っており、のようなものに頼る必要がないため、「OO」の言語でそれを行うにはCでOO可能性が、恐ろしいです- 。

OO構造が言語自体、標準ライブラリ、または他のライブラリによって提供されているかどうかは問題ではありません。一部の言語(Scalaなど)では、ライブラリが言語構造を追加できるため、プログラマーの観点からはほとんど不可能です。コア言語によって提供されるものとライブラリによって提供されるものを区別するため。


2

OOとして広く受け入れられている言語の範囲とそうでない言語の範囲を見ると、テストは包含多型(別名サブタイプ多型ですが、包含多型はCardelliで使用されている用語です)私や他の多くの人に、多型の種類の分類を紹介した論文)。IEは、いくつかの変数が異なるタイプの値を持つ可能性と、1つまたは複数の値のタイプに応じて、いくつかの呼び出しが異なるルーチンにディスパッチする可能性。その他はすべて、OOとして受け入れられない言語で存在するか、OOとして受け入れられる言語から欠落しています。

OO言語に関連する他の2つの主要な特性は、非OO言語によって提供されています。

  • カプセル化はAda83によって十分に提供されています。
  • 継承はOberonによって提供されます(Oberonは興味深いですが、Wirthはオブジェクト言語をできるだけ残さないようにしたかったのですが、彼の概念を再検討して取得する必要がありました-Oberon-2はOOです)。

1

オブジェクトの向きは次のように定義されます

ウィキペディアのエントリも確認してください。これらは、オブジェクト指向として定義されるために言語が提供しなければならない機能です。

オブジェクト指向プログラミング言語の場合は、コードをオブジェクト指向と見なしてください。手続き型のように見えるものを書いても、カプセル化によるポリモーフィズムを使用して、クラスのオブジェクトのメソッドに作用します[たぶん] :)

あなたの最後の質問に関しては答えはおそらくです。はい。オブジェクト指向は基本的にオブジェクトのメソッドに作用し、それらのオブジェクトをパラメーターとして渡します。


3
誰が定義しますか?
Michael Borgwardt 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.