継承、カプセル化、多型がOOPの柱ではないのはなぜですか?[閉まっている]


16

ある日、私はStack Overflowチャットに行って、継承、カプセル化、およびポリモーフィズムがOOPの柱であることを示すフレーズを見ました(それらは基本的なものであり、構築の唯一の意味です)。

また、大学の試験や就職の面接で頻繁に尋ねられる同様の質問があり、正しい答えは常に質問のタイトルで発音された声明でした(「はい、継承、カプセル化、多型はOOPの柱です)。

しかし、Stack Overflowチャットで私はひどく笑され、参加者はそのような声明に強く反対しました。それで、この声明の何が問題になっていますか?

プログラマーはソビエト連邦後の大学とアメリカの大学で異なることを訓練されているように見えますか?

継承、カプセル化、およびポリモーフィズムは、US / UKプログラマーによるOOPの柱と見なされていませんか?


7
あなたの質問には文脈がありません。SOチャットの人々が何を考えているのか、彼らが何に反応していたのかはわかりません。チャットルームの会話にリンクできるので、ご覧ください。とはいえ、これはここではなくチャットルームで解決するのが最善だと思います。
ロバートハーヴェイ14

1
@ロバート、あまりにも長い間。会話へのリンクをまったく見つけることができるかどうかは疑問です。しかし、コンテキストが重要であることに同意します。誰かを非難したり、チャット攻撃の無実の犠牲者になったりするのではなく、真実を知りたいだけです。
PaulD

5
ラウンジ。最初に防炎スーツを着ましたか?
ロバートハーヴェイ14

1
私が文に与えることができる唯一の意味は、「あなたはそれらなしでOOPを持つことができます」(本当ですが、少なくともカプセル化には意味がありません)または「あなたもOOPの外で使用できます」、またはそのようなものです。
SJuan76 14

2
Imo OOには1つの柱しかなく、それは「状態」です。脳が状態を考えると、オブジェクト指向を取得します。
ピーターB

回答:


40

継承、カプセル化、およびポリモーフィズムは、US / UKプログラマーによるOOPの柱とは見なされていませんか?

それらは多くのプログラマーの柱であると考えられており、多くの大学はそのようにオブジェクト指向を教えています。

残念ながら、これは近視眼的な見方でもあります。

  • 継承はOOPの実装に使用されるメカニズムの1つにすぎず、OOPを実行しないために悪用される可能性があります。
  • カプセル化は、OOPではなく、あらゆる種類のプログラミングに役立つ概念です。
  • ポリモーフィズムは、計算の動作を記述するtrait(?)です。ポリモーフィズムを実現するには多くの方法がありますが、そのすべてがオブジェクト指向固有のものではありません。

OOPの基盤はほとんどありません。実際には非常に概念的であるためです。「物事をオブジェクト、つまりまとまりのあるデータと機能のバンドルと考えることでプログラムの設計にアプローチする」。

そして、現代のプログラム設計は「純粋にオブジェクト指向の方法」で物事を行うという見方は貧弱ですが、ほとんどの熟練プログラマーは、SOLID原則(または一部のサブセット)が「オブジェクト指向プログラミングの柱」のより良い候補であることに同意します非OOPにも適用されます)。これらはこれらの用語ではまったく機能しません。代わりに、ソフトウェアエンティティ(オブジェクトは1つ)、インターフェイス(C#/ Javaなどinterfaceは1つ)、抽象化とサブタイピング(継承は1つの形式)の概念を使用します。


10
本質的に答えられない質問に対するまともな答え。
ロバートハーヴェイ14

3
OOPは存在しますか?
Tulainsコルドバ

5
私は、カプセル化だけがOOPの「柱」であると主張します。OOPと構造プログラミングの最大の違いは、オブジェクトにはデータだけではなくコードデータが含まれているという考え方です(たとえば、古典的なC構造体)。他の2つの概念は、主にオブジェクト指向言語で使用されますが、オブジェクト指向に制限されることも、オブジェクト指向言語によって必要とされることもありません。

3
@Snowman EncapsulationもOOPに制限されていません。人々は常にCおよび関数型言語で抽象データ型を実装しています。
ドーバル14

2
そして、@JörgWMittagはメッセージングに関して良い答えを出しました。メッセージングのアイデアには、必ずカプセル化が必要です。通常、メッセージはオブジェクトの関数またはメソッドに渡され、オブジェクトにカプセル化された状態に作用します。それは、非OO言語がメッセージの受け渡しやカプセル化を行うことができないということではなく、これらがOOPの基本的なアイデアであるということだけです。

23

tl; dr:オブジェクト指向なしで継承でき、オブジェクト指向なしでカプセル化でき、オブジェクト指向なしでポリモーフィズムを持ち、オブジェクト指向なしで3つすべてを同時に持つこともできます。一方、継承なしでオブジェクト指向を使用できます。さらに、さまざまな種類のカプセル化(ADT指向とOO)があり、IOWはすべてのカプセル化がOOではありません。

ロングバージョン:

「オブジェクト指向プログラミング」という用語はAlan Kayによって発明されたので、彼はそれが何を意味するかを決定します。そして彼はそれをこのように定義しています

私にとってのOOPとは、メッセージング、ローカルの保持と状態プロセスの保護と隠蔽、およびすべてのものの極端な遅延バインディングのみを意味します。

実装上、メッセージングは​​レイトバインドプロシージャコールであり、プロシージャコールがレイトバインドである場合、設計時に呼び出す内容を知ることができないため、状態の具体的な表現について仮定することはできません。したがって、実際にはメッセージングについてであり、レイトバインディングはメッセージングの実装であり、カプセル化はその結果です。

彼は後に「大きなアイデアは「メッセージング」である」ことを明確にし、「メッセージ指向」ではなく「オブジェクト指向」と呼んだことを後悔しています。「オブジェクト指向」という用語は重要ではないもの)そして、何が本当に重要なのかをそらす(メッセージング):

Smalltalkはその構文やクラスライブラリだけでなく、クラスに関するものでもないことを皆に思い出させようと、最後のOOPSLAで苦労したことを思い出してください。私がずっと前にこのトピックの「オブジェクト」という用語を作り出したことを残念に思う。

大きなアイデアは「メッセージング」です。これがSmalltalk / Squeakの核心です(Xerox PARCフェーズでは決して完成しなかったものです)。日本人は、「間にある」を意味する小さな単語maを持っています。おそらく、最も近い英語の同等語は「インタースティシャル」です。優れた成長可能なシステムを作成するための鍵は、内部のプロパティや動作がどうあるべきかではなく、モジュールの通信方法を設計することです。インターネットを考えてみてください-生きるためには、(a)単一の標準を超えたさまざまな種類のアイデアと実現を許可する必要があり、(b)これらのアイデア間のさまざまな程度の安全な相互運用性を許可する必要があります。

(もちろん、今日、ほとんどの人はオブジェクトではなくクラスに焦点を合わせていますが、これはさらに間違っています。)

メッセージングは、基本的なメタファーとして機構としても、OOへ。

誰かにメッセージを送信した場合、そのメッセージをどう処理するかわかりません。唯一のあなたが観察できる事は、その応答です。メッセージを自分で処理したかどうか(オブジェクトにメソッドがあるかどうか)、メッセージを他の誰かに転送したかどうか(委任/プロキシ)、さらに理解したかどうかはわかりません。それがカプセル化のすべてであり、オブジェクト指向のすべてです。期待どおりに応答する限り、プロキシを本物と区別することさえできません。

「メッセージング」のより「現代的な」用語は「動的メソッドディスパッチ」または「仮想メソッド呼び出し」ですが、それは比metaを失い、メカニズムに焦点を合わせます。

同様の点は、データ抽象化の理解ウィリアムR.クックの再訪、および「オブジェクト」および「オブジェクト指向」の簡素化されたモダンな定義に対する彼の提案にも示されています。

操作の動的なディスパッチは、オブジェクトの本質的な特性です。これは、呼び出される操作がオブジェクト自体の動的プロパティであることを意味します。操作を静的に識別することはできません。また、実行することを除いて、一般に、特定の要求に応じて実行される操作を正確に特定する方法はありません。これは、常に動的にディスパッチされるファーストクラスの関数とまったく同じです。

Smalltalk-72では、オブジェクトすらありませんでした!解析、書き換え、および再ルーティングされたメッセージストリームのみがありました。最初に登場したのはメソッド(メッセージストリームを解析して再ルーティングする標準的な方法)、後に登場したオブジェクト(プライベートステートを共有するメソッドのグループ化)です。継承はかなり後のことであり、クラスは継承をサポートする方法としてのみ導入されました。Kayの研究グループが既にプロトタイプについて知っていたなら、そもそもクラスを導入したことはなかっただろう。

すべてのプログラマーは、データ抽象化の理解について、再訪を読む必要があります。オブジェクトと抽象データ型の正確な違いを詳細に説明します。彼はJavaを使用して例を挙げていますが、ADTの例オブジェクトの例の両方で継承、カプセル化、ポリモーフィズムを使用しいるため、この質問には非常に関連性がありますが、オブジェクト指向の例は1つだけです!言い換えれば:あなたが継承、カプセル化および多型を持つことができ、あなたも一度にすべての3つを持っていることができ、まだ OOを持っていません。

一方、継承なしでオブジェクト指向を使用できます。上記で示唆したように、Smalltalkのオリジナルバージョン(「オブジェクト指向プログラミング」という用語の発明者であるAlan Kayによって設計された言語)には継承がありませんでした。

最後になりましたが、オーランド条約では、委任は継承の代替手段であり、異なる形式の委任と継承がオブジェクト指向言語の設計空間内の異なる設計ポイントにどのようにつながるかについて説明しています。(実際、Javaのような継承をサポートする言語でさえ、人々は実際にそれを避けるように教えられており、オブジェクト指向には不要であることを示していることに注意してください。)


「継承」、「ポリモーフィズム」、「継承」を持つことができます...どこかにタイプミスがあります:)
slebetman 14

1
この回答により、「お気に入り」の回答もできるようになります。
チャンホーSuh

アラン・ケイの定義は時代遅れです。OOには継承が必要です。C++のように実行時とコンパイル時の両方のバインディングを実行できる場合、Cと同等のパフォーマンスが得られます。
エリックアラパエ

いいえ、彼の定義は正しいものです。オブジェクト指向になるために継承はまったく必要ありません。プロトタイプ言語はC ++のような継承を使用せず、引き続きオブジェクト指向です。継承はコードの再利用を実装するためにのみ使用され、最良の方法ではありません。たとえば、ミックスインを備えた優れた言語がたくさんあります。また、仮想メソッドを使用できるC ++でさえ動的バインディングを行うことはできないため、バインディングとは関係ありません。パフォーマンスはこれとは関係ありません。これらは高レベルの概念であり、パフォーマンスはありません。実際には、OO Cでメッセージパッシングを実装し、可能性
ルイス・フェリペ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.