首頁 > Java > java教程 > 主體

畢竟,物件導向的定義是什麼?

王林
發布: 2024-09-06 06:46:01
原創
666 人瀏覽過

Afinal de contas, qual a definição de Orientação a Objetos?

介紹

物件導向範式無疑是程式設計中最相關的主題之一,可以在SOLID、GoF 設計模式或物件Calhistenics 等多個產業最佳實踐中找到,甚至可以在Java 等極其流行的語言中找到、C# 、Ruby、PHP、JavaScript 等。鑑於這種相關性,它也成為線上討論甚至學術界本身爭論的主題。

圍繞著這個範式的主要爭議之一是:物件導向實際上是什麼?由於沒有人就其含義達成一致,這就是各種類型的互聯網爭論中問題的癥結所在,例如當有人聲稱他們的語言是真正面向對象的而其他語言不是,或者某些語言並不是真正面向對象時-定向等

乍看之下這似乎很愚蠢,但這背後隱藏著一個問題,那就是對於什麼是物件導向確實沒有正式的定義。因此,當批評與範式相關的事物時,我們無法確定它是否公平,因為沒有人知道真相到底是什麼,這只會導致雙方都可以指責對方的爭論。攻擊稻草人,因為他們不同意他們所辯論的內容的定義,這導致他們在談論同一件事的同時談論不同的事情。

發生這種情況是因為它不是產生於可以被確定為討論主要來源的正式基礎,例如結構化/程序範式- 它源於Boehm-Jacopini 定理和文章Go-to 聲明被認為是有害的-或者是從lambda演算誕生的泛函,相反,從技術上來說,它有兩個不同的起源,這讓事情變得非常困難,畢竟,甚至很難說哪個是第一個面向對象語言,無論是Simula或Smalltalk。

如果你之前沒有接觸過這個話題,你可能會覺得我在這裡描述的一切有點奇怪,畢竟我們都學習面向對象,我們每天都用文字交流,一切似乎都在正常進行,溝通時沒有噪音,對吧?

您甚至可能認為這很容易,因為即使我們查看不同的來源,例如互聯網上的通用教程、維基百科,或者即使我們接受正規教育(例如技術課程或大學),我們會發現與我所說的非常相似的定義:物件導向的四大支柱:

  • 抽象;
  • 封裝;
  • 繼承;
  • 多態性。

但這實際上只講述了故事的一部分,因為正如我之前指出的,實際上存在兩種不同的物件導向思維流派,一種源自於Simula 中創建的傳統,並由C++ 開發和普及,另一個是在Smalltalk 創造的傳統中發展起來的。

即使我們可以接受C++傳統中歷史勝利的一面(因為目前絕大多數被認為是OO的語言比Smalltalk更遵循其思想),即Simula在對於這4 個支柱,對於它們到底是這4 個還是真的應該是4 個還沒達成共識。例如:

  • C++ 語言的創建者本人認為定義只有 3 個支柱(抽象、繼承和多態性);
  • Eiffel 語言考慮了另一組 6 條原則(類別、斷言、泛型、繼承、多態性和 動態綁定);
  • Smalltalk 語言的創建者表示,他創造這個術語時的意思與我們目前使用的完全不同,並描述它實際上可以歸結為3 個原則(訊息傳遞、封裝和所有的極端後期綁定)東西);
  • Ada語言只定義了3個原則(封裝、繼承、多態);
  • Self 語言是基於 3 個想法(原型、槽和行為),儘管它們有其他名稱,但等同於其他定義中使用的術語(繼承、欄位和訊息交換);
  • Java 語言定義了 5 個概念(封裝、欄位、繼承、方法和物件);
  • C# 語言遵循 4 支柱;
  • Simula 語言的創建者承認沒有具體的定義,但引用了一些他認為被認為是物件導向的語言所共有的概念(物件、類別、繼承、多態性);
  • Python語言引用了4個物件導向的概念(類別、物件、繼承和多態);
  • Ruby語言聲稱遵循Smalltalk的定義,非常強調一切都應該是物件的思想,以及訊息交換;
  • PHP 語言沒有物件導向的官方定義,但我們可以根據它呈現為物件導向的特性推斷出它遵循 4 個支柱;
  • Objective-C 語言沒有物件導向的官方定義,但其手冊建議了以下概念組合(一切都是物件、類別、訊息傳遞、封裝、繼承和多態性);
  • MDN 網站在 JavaScript 語言部分考慮了 3 個概念(類別和物件、繼承和封裝);
  • Grady Booch,《應用程式的分析與設計》一書的作者,定義了 7 個原則(抽象、封裝、模組化、層次結構、類型、並發和持久性);
  • GoF(四人幫:Erich Gamma、Richard Helm、Ralph Johnson 和John Vlissides)在他們的《設計模式:可重用物件導向軟體的元素》一書中將封裝、繼承和多態性引用為過程中的「設計模式」語言;
  • Peter Van Roy 在他的《電腦程式設計概念、技術與模型》一書中,將 OO 描述為 4 個項目(抽象機制、顯式狀態、多態性與繼承等物件);
  • ISO/IEC 2382 第2122503 項,這是最接近正式定義的,考慮了6 個原則(抽象、封裝、繼承、多態性、訊息交換和動態綁定);
  • Yegor Bugayenko 透過他創建的稱為 phi-calculus 的形式模型來定義它,並用他的 EOLANG 語言實作;
  • 等等...

定義視角

這樣,正如 Bjarne Stroustrup(C++ 之父)在他的物件導向定義中所論證的那樣:

「物件導向」的任何定義在歷史上都應該是可以接受的。言語僅用於溝通,只有當我們就其意義達成一致時,它們才有意義。

~ Bjarne Stroustrup,改編自英文免費翻譯

這就是為什麼我想採用整體方法(分析整體而不是部分的聲音)來分析我的定義應該考慮什麼。在此我將根據 4 個標準按重點順序進行評估:

  1. 概念與定義的視角一致;
  2. 歷史相關性;
  3. 實踐中的實現(也將被視為常識感知);
  4. 物件導向的排他性(概念可以被辨識為物件導向的東西的程度,而不是來自 X 或 Y 範式的東西,或更一般的概念);

讓我們先定義我們的歷史起點,首先我們將決定選擇哪一邊作為主要來源,然後遵循其作者的物件導向意義作為我們定義的基礎,除了使用它作為比較參數來判斷哪一組原則包含在其中是有意義的。

この質問に関して、私はアラン・ケイが「オブジェクト」ではなく「オブジェクト指向」を発明したという見解が好きです。そのため、私たちの基礎となるのは、オブジェクト指向がどうあるべきかについての彼の見解であり、それはいくつかの引用で要約できます。

前回の OOPSLA では、Smalltalk が単なる構文やクラス ライブラリではなく、クラスに関するものでもないことを皆さんに思い出してもらうために、私が懸命に取り組んだことをもう一度思い出させてください。私は、ずっと前にこのトピックのために「オブジェクト」という用語を作ったことを後悔しています。なぜなら、それによって多くの人がより小さなアイデアに注目することになるからです。

大きなアイデアは「メッセージング」です - それが Smalltalk/Squeak の核心です...

~ アラン・ケイ、英語から意訳

私は、メッセージを通じてのみ通信できる、ネットワーク上の生物細胞や個々のコンピューターのようなオブジェクトを考えました (つまり、メッセージは早い段階で登場しました。プログラミング言語で十分に効率的にメッセージを送信する方法を理解するには、しばらく時間がかかりました)便利です)。

データを削除したかったのです。 B5000 は、ほとんど信じられないようなハードウェア アーキテクチャを通じてこれをほぼ実現しました。細胞とコンピューターのメタファー全体がデータを削除し、「<-」は単なるメッセージ トークンに過ぎないことに気づきました (実際、これらすべての記号を関数の名前と考えていたため、これを考えるのに時間がかかりました)手順。

私の数学の背景により、すべてのオブジェクトにはそれに関連付けられた複数の代数があり、これらの族が存在する可能性があり、これらが非常に役立つことに気づきました。 「ポリモーフィズム」という用語は、ずっと後になって (Peter Wegner によってだと思います) 課せられたもので、実際には関数の命名法に由来しているため、あまり有効ではありません。私は関数以上のものが欲しかったのです。私は、一般的な動作をほぼ代数的な方法で扱うために、「ジェネリック性」という用語を発明しました。

私は、Simula I や Simula 67 の継承の方法が好きではありませんでした (Nygaard と Dahl は単に素晴らしい思想家でありデザイナーだと思っていましたが)。そこで、よりよく理解できるまで、組み込み機能としての継承を省略することにしました。

~ アラン・ケイ、英語からの意訳

私にとって POO とは、メッセージ交換、ローカル データの保持、国家の保護と隠蔽、そしてあらゆるものの極端な遅延バインディングを意味します。

~ アラン・ケイ、英語から意訳

これにより、Kay の定義を使用してオブジェクト指向プログラムを見るための 視点 は次のとおりであると結論付けることができます。

プログラムは、メッセージの交換を通じて通信するオブジェクトのネットワークとして見なされます。その目的は、データを回避し、対話に焦点を当ててプログラムすることで、メッセージが複数の意味を持たせることができるようにすることです。

視点と言えば、これは Simula の作成者が著書『BETA プログラミング言語のオブジェクト指向プログラミング』でフレームワークの概念的な枠組みを説明するために使用したセクションです。つまり、フレームワークの構造をどのように見るかについての説明です。特定のパラダイムで書かれたプログラム、たとえば手続き型プログラミングの場合、次のように説明されます:

プログラムの実行は、変数を操作する一連の (部分的に順序付けられた) プロシージャ呼び出しとみなされます。

~ Nygaard はまったく、英語からの意訳

関数型の場合:

プログラムは、入力と出力の関係を記述する数学関数とみなされます。

~ Nygaard はまったく、英語からの意訳

オブジェクト指向の場合:

プログラムの実行は物理モデルとみなされ、世界の実数部分または虚数部分の動作をシミュレートします。

~ Nygaard はまったく、英語からの意訳

つまり、私たちがアラン・ケイの定義に焦点を当てているとしても、オブジェクト指向言語に見られる機能に関するクリステン・ナイガードとオーレ・ヨハン・ダール(Simula の作成者)の多大な貢献と、彼の視点がどれほど古くなっているかを考えると、現代のほぼすべてのチュートリアルが、オブジェクトが現実世界の概念を表すというこのストーリーに従っており、抽象化の定義の一部として形式化されていることを考えると、彼の見解を最終的な定義に組み込むのが適切であると言えます。

したがって、全体的な分析への私たちのアプローチを尊重して、2 つの伝統を統一された定義に調和させるための議論ができる場合には、私はそうしてみます。

したがって、必ずしも現在の定義に限定されるものではないため、次のように増やすことができます:

プログラムはオブジェクトのネットワークとして見なされ、これらはドメイン概念の表現であり、メッセージの交換を通じて通信します。その目的は、メッセージが複数の意味を伝えることができるように、データを回避し、対話に焦点を当ててプログラムすることです。その一般的な構造は、世界の実数部分または虚数部分の動作のシミュレーションに似ています。

考慮すべき点の 1 つは、これが人々を「より小さなアイデア」に集中させる可能性があるということですが、以前に認めたように、言葉は人々が理解する場合にのみ価値があるため、時間の経過とともにアイデアがどのように進化するかを認識する必要がありますしたがって、この視点は、アラン・ケイの当初の目的を維持することと、ナイガードとダールのオブジェクト システムの価値観を組み込むこととの間で十分なバランスが取れていると信じています。

概念の定義

現在の定義文で、私はすでに満足できます。これが、この記事で提示された質問に対する私の答えです。しかし、パラダイムの完全な定義には、それが表すものについての「視点」の両方が含まれるべきだと私は信じています。プログラムの実行とそれに関連する一連の原則。

したがって、私たちは半分のところまで来たと言えます。そして今、私が以前に示した定義の広範なリストに戻って、私たちの基本的なビジョンを裏切らない範囲でどの原則が私たちの視点に適しているかを探すことができます(メッセージの交換に焦点を当てます) .

これについては、もう一度、主要な情報源である Smalltalk の OO 原則に戻りましょう。

  • メッセージを交換する;
  • ローカル データの保持、および国家の保護と隠蔽;
  • 極端な 遅延バインディング

歴史的関連性の基準を再度使用する場合、これらの用語は現在では (メッセージ交換を除いて) 使用されていないため、代わりに 4 つの柱を使用することを検討する必要があると主張する可能性があります。ここでの融和的なアプローチは、矛盾なく両方の長所をとったものとなるでしょう:

  • メッセージを交換する;
  • ポリモーフィズム;
  • カプセル化;
  • 抽象化;
  • 継承;

これらの 5 つの原則を選択するための説明があります:

メッセージの交換

メッセージの交換は、OO の元のコンテキスト内では交渉の余地のないものです。結局のところ、アラン ケイはパラダイムの大きなアイデアであり、その最も重要な概念であると主張しています。だからこそ、他のすべての概念には何かが必要です。それをやります。

Self、Objective-C、Ruby などの歴史的関連性を持つ言語はこの概念との強いつながりを維持しており、Ruby 自体は今日では主流の言語とみなされており、優れたアプリケーションが構築されているため、実際の採用はかなりの量です。非常に活発なコミュニティがあることに加えて、github 自体と同様です。

そして、継承とカプセル化とともに、これは OO のアイデンティティを最も伝える概念の 1 つであると言えます。なぜなら、この用語が使用される他の 2 つのインスタンス (意図的なジョーク) はアクター モデル内にあるためです。は、基本的に Alan Kay とほぼ同じアイデアを持つ数学モデルの形式ロジックですが、完全に同時実行性に基づいています (OO のようなものは、JS 開発者が理解できるように 100% 非同期でした)。

ポリモーフィズム

これは私たちの分析の基準をすべて満たす概念です。Nygaard と Dahl が指摘したように、暗黙的であっても (継承をサポートしている場合は、ポリモーフィズムも暗黙的にサポートされています)。

それを使用することの自然な利点であるため、メッセージを交換するという考えとも非常に一致しています。さらに、これはアラン・ケイの定義にも存在します (ただし、彼は汎用性という用語を好むと述べています) 結局のところ、遅延バインディング は言語に存在するプロセスの名前です
関数の呼び出しを特定のコードに関連付けるのではなく、コンテキスト (OO の場合、メッセージを受信するオブジェクト) に基づいて実行できるようにするプログラミングです。これはまさにポリモーフィズムの定義です。 .

一般の認識という点では、これはリストされた 5 つの概念の中で最も重要な概念であり、ボブおじさんによって OO の本質として定義されています。さらに、オブジェクト指向で正確にプログラムする予定がない状況でも、これは、六角形のアーキテクチャやクリーンなアーキテクチャなどのいくつかのアイデアを構築するための基本的なブロックとしての原則と見なされます。

ただし、この概念は OO に固有のものではなく、いくつかのパラダイム全体に存在するより一般的な概念であり、多くの場合、同じ言語で異なる型の実装が行われます。それにもかかわらず、言語の継承を実行する能力に依存する型であるため、特にサブタイプ多態性は OO に固有であると主張することができます。

カプセル化

この主題に関する私たちの記事を読んだことがあれば (はい、私たちはこのあたりの定義について話したいのです)、「国家の保護と隠蔽に加えて、ローカルでのデータ保持」という言い方が基本的に完全な定義であることがわかるでしょう。カプセル化 なので、概念的な調整側は、以前のものと同様に、ここでもこの原則に 100% 準拠しています。

一部の言語では原則としてカプセル化について言及していませんが、オブジェクトを持つという事実 (または Java や Self の場合のように、オブジェクト内のフィールドの概念を強調) という概念が半分でもそれらの言語に存在します。これは、データをその機能 (オブジェクト自体) とともにローカル コンテキストでのみ操作し続けるメカニズムがあることを示しています。一方、C++ や Eiffel などの言語は、フォーム内の状態を保護および非表示にするメカニズムを提供します。アクセス修飾子 (C++) またはアサーション、事前条件、事後条件、および不変式 (Eiffel) の。 Java には、カプセル化の適用について正確に論じたオブジェクト指向に関する最も有名な記事の 1 つさえあります。「なぜゲッターとセッターは悪であるのか。

したがって、これは時の試練の中で非常によく成熟した原理であると言えますが、それでもポリモーフィズムと同じ批判を受ける可能性はあります。なぜなら、それは OO にのみ関連付けられた概念ではないためです。モジュール (シングルトン オブジェクトを持つのと似ています) またはクロージャを使用してこれを実現します。これらは貧乏人のオブジェクトとして機能する可能性があるためです。ただし、ポリモーフィズムの場合と同様に、この概念は OO で「独特の風味を持って」適用されます。ローカル データ保持メカニズムがオブジェクトであり、情報の隠蔽はアクセス修飾子を通じて行われるため、このパラダイムに広く関連付けられている機能です。

抽象化

残りの 4 つの柱ほど出現しませんが、カプセル化と同様に、Self を除いて言及されているすべての言語にはメカニズムがあるため、その存在は明示的ではなく暗黙的に感じられます。クラス形式のデータ抽象化。

自己の問題に入り、彼はオブジェクト自体とメッセージの交換を非常に重視しています。それを利用して概念の調整の問題を分析できます。この場合、それはプログラミングだと言えます。メッセージを交換することは、より現代的な言葉で言えば (概念はまったく同じではありませんが)、「インターフェイスのプログラミング」と同じになります。つまり、最終的な実装が実際にどうなるかを気にせずに、抽象化のみを使用してプログラミングすることになります。これは、アレック・シャープ著『Smalltalk by Example: The Developer's Guide』という本で「オブジェクト指向のプログラミング方法」として説明されている非常に優れたメソッドです。

ポリモーフィズムと組み合わせた抽象化のアイデアにより、あらゆるメッセージ交換メタファーが動作できるようになります。メッセージを見るだけでは、コードの実行結果がどうなるかを知る方法はないという考えです。それらはすべて抽象化であり (最新の OO でインターフェイスのメソッドを読み取るときに、物事がどのように実行されるかを知ることができないのと同じ意味で)、結果はオブジェクト自体にある具体的な実装に依存します。どのオブジェクトがそのメッセージに応答するかによって異なる場合があります。

ピーター・ヴァン・ロイ氏の記事「プログラミング・パラダイム・フォー・ダミー」で述べられているように、データ抽象化はパラダイムの概念を上回る一般原則であるため、すべての原則の中で、排他性の基準において抽象化が最も弱いと言えます。繰り返しになりますが、他の原則と同様の状況にあり、クラスという非常に特徴的なメカニズムが使用されています。クラスはオブジェクト指向の機能として広く認識されているため、パラダイムはプログラミングに限定されていると多くの人が考えています。クラス (オブジェクトを忘れたり、さらに悪いことに、プロセス内のメッセージを忘れたりする場合もあります)。

遺産

彼女はメッセージ交換とは逆の理由でここにいます。交換するメッセージの一般認識スコアが低いが、概念的な整合性が最も高い場合、継承は選択された概念の概念的な整合性が最も低くなります (これは、アラン・ケイが Smalltalk に遺産を追加したのは、それが何に使用されるのか実際には分からなかったが、役立つかもしれないと思ったからであるという引用)、しかし、それは非常に高い歴史的貢献に加えて、最も大きな世間の認識を持っています。

そもそも、これは Simula の主要な機能の 1 つであり、Smalltalk 以降の時代には OO の本質と考えられていましたが、継承ではなく合成というアイデアが出版された後、これは完全に逆転しました。 GoF.

これにもかかわらず、これは OO にのみ関連付けられている唯一の概念であり、多くの場合、その存在だけで言語をオブジェクト指向として区別するのに十分な機能です。これに反する唯一の議論は、レコード に関する Hoare のアイデアですが、これは Simula での継承と製品タイプを生み出したものでしたが、これは継承とはまったく異なる主題であり、どちらでもないあなたも同じ問題や論争に苦しんでいます。

結論

最終的に、視点と原則の両方が得られたので、最終的な定義は次のようになります:

オブジェクト指向プログラムはオブジェクトのネットワークとして見なされ、これらはドメイン概念の表現であり、メッセージの交換を通じて通信します。その目的は、メッセージが伝達できるように、データを回避し、対話に焦点を当ててプログラムすることです。いくつかの意味。その原則は、メッセージ交換、ポリモーフィズム、カプセル化、抽象化、継承です。一般的な構造として、世界の実数部分または虚数部分の動作のシミュレーションに似たものがあります。

とにかく、これが記事のタイトルで提示された質問に対する私の最終的な答えです。この調査全体には多大な労力がかかりました。そのため、この文章が少なくとも何か新しいことを教えてくれたり、いくつかの考察につながったりしたことを願っています。

私の定義に同意するか反対する場合は、コメント欄で意見を共有することを忘れないでください。また次回お会いしましょう!

興味がありそうなリンク

  • プログラミングパラダイムに関するウィキペディア;
  • ポリモーフィズムに関するウィキペディア;
  • C2 Wiki - OO が何であるかについては誰も同意しません;
  • C2 Wiki - オブジェクト指向プログラミング;
  • Stackoverflow - 「オブジェクト指向」用語の意味;
  • EOLANG とファイ微積分学;
  • コンピューター プログラミングの概念、技術、モデル;
  • ダミーのためのプログラミング パラダイム;
  • 例による Smalltalk;
  • BETA プログラミング言語によるオブジェクト指向プログラミング;
  • C++ が単なるオブジェクト指向プログラミング言語ではない理由
  • アラン・ケイ博士が「オブジェクト指向プログラミング」の意味について語る;
  • オブジェクト指向の誕生: Simula 言語;
  • オブジェクト指向プログラミングの 2 つの大きな学校;
  • ISO/IEC 2382:2015;
  • SelfObjectModel;
  • セルフハンドブック;
  • 自己: シンプルさの力;
  • ダイナミック vs.静的ディスパッチ;
  • OOP の (間違った) 解釈;
  • 新しいオブジェクト クロージャから単純なオブジェクト システムを構築する;
  • シンプルなメタオブジェクト プロトコルを構築する;
  • ディスパッチインターフェイス;
  • アラン・ケイとOOプログラミング;
  • アラン・ケイは物を発明したわけではありません;
  • プロトタイプとクラスの比較: Re: Sun の HotSpot;
  • コンピュータプログラムの仕様と組織の将来について;
  • データレス プログラミング;
  • Smalltalk の初期の話;
  • Go To ステートメントは有害であると考えられます;
  • ベーム・ヤコピニの定理;
  • エッフェル塔 OO について;
  • OO よりも Devmedia;
  • ラムダ計算に関するウィキペディア;
  • OO についてのエイダ;
  • Java 仕様第 3 版;
  • OO よりも C#;
  • OO 上の Python;
  • OO を介した PHP;
  • Ruby ドキュメント;
  • OO を介した MDN;
  • アプリケーションを使用したオブジェクト指向の分析と設計;
  • デザインパターンブック;
  • ゲッターとセッターが悪である理由;
  • Clean Coder ブログ - FP vs. OO;
  • アクターモデルに関するウィキペディア;
  • アクターモデルに関する Akka (プログラミング言語);
  • 俳優モデルについて堂々と;

お尻: 疲れたサポート

以上是畢竟,物件導向的定義是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板