OOPに不可欠な概念の一貫した定義がないのはなぜですか?


12

私はプログラミングを始めたばかりで、さまざまなソースのさまざまな慣習を読んだり聞いたりすることから少し混乱しています。

オブジェクト指向プログラミングには4つまたは5つの概念がありますか?

新参者として、私はこれらが5つの概念であることを理解しています:

  • 抽象化
  • 継承
  • カプセル化
  • 多型
  • モジュール性

では、どうして「厳密な」定義が見つからず、これらの概念のいくつかのアレンジがそこにあるように思えますか?


7
たぶんそれは数学のようではないからです(CSのいくつかの概念はそうですが、OOPはこのカテゴリに属していないと思います)。したがって、厳密な定義はありません。たとえば、「モジュール性」はどれほど重要ですか?OOPに本当に特別なものがあるので、言及する必要がありますか、それとも他の4つを正しく適用した場合に自然に発生するものですか?一部のリストには「階層」が追加されていますが、これは本当に余分なものですか、それとも継承とポリモーフィズムの結果ですか?
トーステンミュラー16年

6
アドバイス:非常に新しいプログラマーとして、用語と理論を理解することに夢中になるべきではありません。最初にいくつかの実践的なプログラミングの経験を集めてください。そうすれば、これらの人々が何について話しているかがより明確になります。
フィリップ

9
もう1つは、OOPが時間とともに変化していることです。初期のC ++時代(OOPがそれよりもさらに遡ることは知っています)の多くの焦点は、継承とポリモーフィズムにありました。今日の焦点は、抽象化とカプセル化です。
ベント

3
OOの定義の精度の欠如に関する興味深い議論は、c2.com
cgi

回答:


27

オブジェクト指向プログラミングが何を意味するかについてさまざまな説明を見つけるのは、厳密に普遍的に適用可能な定義を策定する権限を持つ単一の個人または組織が存在しないためです。

オブジェクト指向プログラミングは、ISO標準でも科学法でもありません。それは哲学です。また、すべての哲学と同様に、あらゆる種類の異なる解釈があり、普遍的に適用可能な解釈はありません。ソフトウェアアーキテクチャを設計するときに従うべき概念を説明するテキストを読むとき、これは普遍的な真実としてではなく、専門家の経験の中で作者が形成した意見に基づくガイドラインとして見るべきです。


12

オブジェクト指向プログラミングには5つまたは4つのコンポーネントがありますか?

他の人が言ったように、「OO」は実際にはコンポーネントを持ちません。なぜなら、それはツールキットや明確に定義されたプロセスのセットではなく、問題のモデリングソリューションを考える方法だからです。

新参者として、私はこれらが5つのコンポーネントであることを理解しています。

抽象化、継承、カプセル化、多態性、モジュール性?

継承とポリモーフィズムはプログラミング言語の機能です。これらを理解することは良いことですが、それらはツールであることを忘れないでください(つまり、他のツールと同様に、特定の問題を解決するためにのみ使用し、目標や努力するものとして扱わないでください)。どちらも使用せずに「OO」コードを書くことができます(また、そうすべきです)。私が今まで見た中で最高の「OO」コードのいくつかは、継承やポリモーフィズムをほとんど使用していません。

抽象化、カプセル化、モジュール化は、コードとは関係がなく、問題の見方、その問題を理解しようとする方法、コードでソリューションを設計および構造化する方法に関するものです。

また、これらのデザインアイデアは「OO」に限定されません。おそらく今、おそらく基本レベルでそれらを理解している可能性があります。これには、教科書の完璧な定義を説明し、多少自明でない問題に適用できることが含まれます。理解のより深いテストには、非常に大きな複雑な問題と、どれだけの複雑さを処理できるかが与えられています。

別の理解のテストは、問題を分解するために使用するアプローチです。「OO」の新参者は、データモデリングの観点からOOについてよく教えられます(ほとんどの人が1990年代にOOを理解していたためです)。データにあまりにも多く、行動に十分に焦点を合わせていません。

例えば、典型的な例は、多くの場合のような実体を参照してくださいDogCatElephantSeagullShark、など、多くの場合、このような例を見て、すぐに考える「OO」の新人「ああ、私はと呼ばれる基本エンティティを必要とするAnimal、そして彼らも他に終わる可能性がありなどの中間エンティティMammalAmphibianそれぞれに異なる属性を持つニート継承階層構造で、。

その考え方はいくつかのオブジェクト指向の概念の非常に基本的な理解を示していますが、経験豊富なオブジェクト指向プログラマーはそのようなアプローチに決して至らず、その結論に飛び込むことはありません(そして実際には彼らが十分な情報を持っていないことを訴えます) OOモデリングではなく、モデリング。そして、これらの動物の行動について不自然な例は何も述べていないため(そして多くの人々は、OO の本質はすべて行動と機能にあると主張します)。

「OO」について学ぶための道は、モデリングしている問題の振る舞いについて何も知らない(または少なすぎる)場合、またはエンティティではなくエンティティに注意を集中するミスを犯した場合に、間違った抽象化の構築に時間を費やすことですその理由の一部は、長年にわたって書かれた非常に多くの書籍、コース、オンラインチュートリアルが、学習者を長い間その道筋に導いた(誤った)ためです(ただし、潮流は変化しています)。

全体的に、あなたの理解の多くは経験に帰着します。これまでに学んだこれらの概念は良い出発点です。途中で学ぶ必要のある概念がもっとあります(たとえば、 "SOLID"および "DRY"の原則)。理論が実際に非常に複雑な問題を実践するようになります。


2
サメとカエルはどちらも泳ぎますが、一方は魚で、もう一方は両生類です。その例はあなたのポイントをよく説明していると思います。
ラバーダック

10

「オブジェクト指向」という用語はアラン・ケイ博士によって造られたので、彼はそれが何を意味するかに関する権威ある情報源であり、彼はそれを次のよう定義しています

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

それを分解しましょう:

  • メッセージング(Smalltalkに慣れていない場合は、「仮想メソッドのディスパッチ」)
  • 状態プロセスは
    • ローカルに保持
    • 保護された
    • 隠された
  • すべてのものの極端な遅延バインディング

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

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

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

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

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

メタファーとメカニズムの両方として、メッセージングはオブジェクト指向の基本です。

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

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

したがって、Alan Kayの定義を見るには2つの方法があります。それを単独で見ると、メッセージングは​​基本的にレイトバインドプロシージャコールであり、レイトバインディングはカプセル化を意味するため、#1と結論付けることができます。 #2は実際には冗長であり、OOはすべて遅延バインディングに関するものです。

しかし、彼は後で重要なことはメッセージングであると後で明らかにしたので、異なる角度からそれを見ることができます:メッセージングは​​遅刻です。さて、メッセージングが唯一の可能性であれば、#3は当然のことです。1つだけのものがあり、その事が遅延バインディングである場合、すべてのものは遅延バインディングです。また、メッセージングからカプセル化が続きます。

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

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

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

型とプログラミング言語の Benjamin Pierceは、オブジェクト指向の定義機能はOpen Recursionであると主張しています。

Alan Kayによると、オブジェクト指向はメッセージングに関するものです。William Cookによると、OOはすべて動的メソッドのディスパッチに関するものです(これは実際には同じことです)。Benjamin Pierceによれば、OOはすべてオープン再帰に関するものです。つまり、基本的には、自己参照が動的に解決されること(または少なくともそれを考える方法)、つまりメッセージングです。

ご覧のとおり、「OO」という用語を生み出した人はオブジェクトについてかなり形而上学的な見解を持ち、クックはかなり実用的な見解を持ち、ピアスは非常に厳密な数学的見解を持っています。しかし重要なことは、哲学者、プラグマティスト、理論家がすべて同意するということです!メッセージングは​​オブジェクト指向の1つの柱です。限目。

ここでは継承については言及していないことに注意してください!OOには継承は必須ではありません。一般に、ほとんどのオブジェクト指向言語には実装の再利用の方法がありますが、必ずしも継承である必要はありません。たとえば、何らかの形式の委任も可能です。実際、オーランド条約では、委任は継承の代替手段として議論されており、異なる形式の委任と継承がオブジェクト指向言語の設計空間内の異なる設計ポイントにどのようにつながるかについて説明しています。(実際、Javaのような継承をサポートする言語でさえ、人々は実際にそれを避けるように教えられており、オブジェクト指向には必要ないことを再び示しています。)


1
@DavidArnoあなたのコメントは建設的なものではありません。アラン・ケイ自身が、この概念の「オブジェクト」という用語を作り出したと主張しています(ただし、概念そのものではありません)。あなたが主題に関する有名な権威と矛盾するつもりなら、少なくともより建設的なコメントを書いてください。
アンドレスF.

1
@DavidArnoまた、下票はあなたのものですか?だから、誰かがOOPの意味について、有名な専門家からさまざまな見解の包括的なリストを書くのに時間をかけましたが、あなたは単一の文に同意しないのでそれを否定しましたか?オーケー
アンドレスF.

2
@AndresF。この答えは「アラン・ケイと他のみんなの2つの学校があります。前者は彼が自動的に正しいという用語を作り出したので、彼に反対する人は皆間違っている」と要約できます。それは権威の誤fallに対する答えです。したがって、下票。
デビッドアルノ

2
実は、この答えのようにまとめることができる「がある3つの思考の学校が誰で三の全く異なる角度と誰もが不一致から、実際には、彼らは合意にすべてです。」言語の処方主義者は、アラン・ケイがこの用語を発明し、それが何を意味するのかを言うようになり、それがメッセージングを意味すると言います。言語的descriptivistはアラン・ケイが、我々は用語がされたかを見ている、何を言って取得していない、いない、と言うだろう実際に使用し、クックがやったことのあること:彼はどのような一般的にOO(Javaの、Cと記載されている言語を学ん++ 、C#など)に共通点があり、彼が見つけた
ヨルグWミットタグ

3
1つのこと:メッセージング:彼は、一般的にOOではないと記述されている言語には欠けていると一般的に記述されている言語に欠けているものを研究し、1つのことを発見しました:メッセージング。アイボリータワーの理論家は、λ計算を使用して、一般にOOと呼ばれるものを取得するために追加する必要がある機能の最小セットを調べ、オープン再帰に到達します。これは、基本的にメッセージングのビルディングブロックです。 。
ヨルグWミットタグ

3

@Philippが述べているように、問題の根本は、プログラミング言語をオブジェクト指向にするものの公式な定義がないことです。確かに、これはおそらく良いことです。オブジェクト指向プログラミングをサポートする方法はたくさんあり、それぞれに長所と短所があります。どの言語がより「純粋なオブジェクト指向」であるかについての議論は、実際にはあまり達成されません。

しかし、あなたがリストした5つの属性を見ると、私の考えではモジュール性は間違いなく奇妙です。モジュール性は、実際にはプログラミング言語ではなくプログラムの属性です。言語レベルでは、属性は「モジュール化のサポート」であり、通常は「モジュール」または「パッケージ」メカニズムの形式をとります。

しかし、モジュラー性に対する私の本当の反対は、典型的なプログラミング言語Smalltalk-80がモジュールをまったくサポートしなかったという点で、OOプログラミングまたはOOプログラミング言語の鍵ではないということです。考えてみると、広く使用されている多くのOOPLでのモジュールの言語サポートは「弱い」です。

モジュールは「大規模なプログラミング」をサポートするように設計されています...コードベースが大きくなりすぎて、一人では完全に理解できません。また、コードをモジュール化するためにプログラミング言語のモジュールは必要ありません。


私は、他の4つの属性、および(たとえば)「継承」のモデルが純粋なオブジェクト指向であるかどうかについても議論していません。また、Alan KayはOOプログラミングを考案したとされていますが、必ずしもOO /およびOOPLの定義に優位性があることを意味するわけではありません。明らかに、そうではありません。彼は、ある信頼できるソースが、(実際には)大きな重量を運ぶことOO&OOPLsのための他の定義を与える他のソースがあります。


2
+1モジュラリティは、実際、使用されているプログラミング言語やパラダイムに関係なく、ほとんどのソフトウェアシステムの望ましい属性として広く受け入れられています。オブジェクト指向ではない多くの言語は、モジュール化をサポートしています。
アンドレスF.

+1 @AndresF。コメント。確かに、「構造化プログラミング」と「段階的な改良」(コード構造を考える手法)は、「複雑さが増し、さらに悪いソフトウェアになる」というるつぼから出てきます。言語がそのような否定的な評判を持たないことがCOBOLに先行していたなら、私見。そして私は、オブジェクト指向を実用的には単に高次の構造と見なしています。そして、基礎となる構造OOなしでは、最悪のCOBOLよりも優れているということです。
レーダーボブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.