質問

意味のある用語のない議論は 意味のない, 、私は部屋の中の象を指さしてこう尋ねようと思った。正確に何が言語を「オブジェクト指向」にするのでしょうか?ここで私が探しているのは教科書的な答えではなく、それが何であれ、自分の分野でうまく機能する OO 言語の経験に基づいた答えです。

最初に回答するのに役立つ関連質問は次のとおりです。オブジェクト指向言語の原型とは何ですか?またその理由は何ですか?

役に立ちましたか?

解決

オブジェクト指向の定義 もちろんです 巨大な虫の缶詰, 、しかし、ここに私の2セントがあります:

私にとって、オブジェクト指向とは、メッセージを送信して連携するオブジェクトのことです。これが私にとって、オブジェクト指向言語の最も重要な特性です。

オブジェクト指向言語に必要なすべての機能の順序付きリストを作成する必要がある場合は、次のようになります。

  1. 他のオブジェクトにメッセージを送信するオブジェクト
  2. すべてはオブジェクトです
  3. レイトバインディング
  4. サブタイプ多態性
  5. 継承または同様の表現力のあるもの、たとえば 代表団
  6. カプセル化
  7. 情報の隠蔽
  8. 抽象化

明らかに、このリストには非常に物議を醸すものがあります。なぜなら、オブジェクト指向として広くみなされているさまざまな言語が除外されているからです。 ジャワ, C# そして C++, 、これらはすべてポイント 1、2、3 に違反しています。ただし、これらの言語でオブジェクト指向プログラミングが可能であることは疑いの余地がありません (ただし、オブジェクト指向プログラミングも可能です)。 C)さらにそれを促進します(Cはそうではありません)。そこで私は、これらの要件を満たす言語を「純粋なオブジェクト指向」と呼ぶようになりました。

典型的なオブジェクト指向言語として私が挙げるのは 自己 そして ニュースピーク.

どちらも上記の要件を満たしています。どちらもにインスピレーションを得たものであり、その後継者です 雑談, 、そして実際には両方とも、ある意味で「より多くのOO」になることができます。私が Self と Newspeak について気に入っている点は、どちらもメッセージ送信パラダイムを極端に取り入れていることです (Newspeak は Self よりもさらに優れています)。

ニュースピークでは、 すべて メッセージ送信です。インスタンス変数、フィールド、属性、定数、クラス名はありません。これらはすべてゲッターとセッターを使用してエミュレートされます。

自己の中には、 授業はありません, 、オブジェクトのみ。これにより、OO とは何かが強調されます。 本当に について:クラスではなくオブジェクトです。

他のヒント

Booch 氏によると、次の要素があります。選考科目:

  • 抽象化
  • カプセル化
  • モジュール性
  • 階層 (継承)

マイナー:

  • タイピング
  • 同時実行性
  • 持続性

基本的にオブジェクト指向は、結局のところ「メッセージパッシング」に集約されます。

手続き型言語では、次のような関数を呼び出します。

  f(x)

そして、名前 f はおそらくコンパイル時にコードの特定のブロックにバインドされます。(これが高階関数または関数へのポインターを備えた手続き型言語である場合を除きますが、その可能性はしばらく無視しましょう。) したがって、このコード行は明確な意味を 1 つだけ意味します。

オブジェクト指向言語では、おそらく次のようにメッセージをオブジェクトに渡します。

 o.m(x) 

この場合。m はコード ブロックの名前ではなく、「メソッド セレクター」であり、どのコード ブロックが実際に呼び出されるかは、何らかの形でオブジェクト o に依存します。このコード行は、o に応じて、さまざまな状況で異なることを意味する可能性があるため、より曖昧または一般的です。

ほとんどの OO 言語では、オブジェクト o には「クラス」があり、そのクラスによってコードのどのブロックが呼び出されるかが決まります。いくつかの OO 言語 (最も有名なのは Javascript) にはクラスがありませんが、実行時にメソッドが直接アタッチされているか、プロトタイプからメソッドが継承されています。

私の結論は、言語が OO であるためにはクラスも継承も必要ないということです。ただし、このような多様なメッセージの処理は不可欠です。

たとえば C の関数ポインターを使用してこれを偽ることはできますが、独自のインフラストラクチャを実装する必要があるため、C を OO 言語と呼ぶにはそれだけでは十分ではありません。それは可能ですし、OO スタイルも可能ですが、言語がそれを与えてくれませんでした。

実際に OO であるのは言語ではなく、コードです。

オブジェクト指向の C コード (必要に応じて構造体や関数ポインター メンバーも使用) を記述することは可能であり、私はその非常に良い例をいくつか見てきました。(Quake 2/3 SDK が思い浮かびます。) プロシージャルを記述することも間違いなく可能です (つまり、非 OO) C++ のコード。

それを考えると、それが「オブジェクト指向の言語」になるのは、優れたOOコードを書くための言語のサポートだと思います。たとえば、普通のメンバー関数となるものについて、Cの構造体で関数ポインターメンバーを使用することを気にしません。したがって、C は OO 言語ではないと言います。

(これを拡張すると、Python はオブジェクト指向ではないとも言えます。すべてのステップで必須の "self" 参照が必要であり、コンストラクターが呼び出されます。 初期化, 、何でも。しかしそれは宗教的な議論です。)

Simula が最初の OO 言語としてよく引用されますが、Smalltalk は通常、典型的な OO 言語とみなされます。

現在の OO 言語は、どの言語から概念を最も多く借用しているかによって大まかに分類できます。

  • Smalltalk のようなもの:Ruby、Objective-C
  • シミュレーションのようなもの:C++、オブジェクト パスカル、Java、C#

私の知る限り、言語を「オブジェクト指向」にする主な考え方は、データとそのデータを操作するメソッドをグループ化するという考え方をサポートすることであり、これは通常、クラス、モジュール、継承、ポリモーフィズムなどを通じて実現されます。

見る この議論 人々がオブジェクト指向をどのように考えているのか (考えたのか?)、その概要を説明します。

「典型的な」OO 言語については、クリストファー氏が指摘したように、まさに Smalltalk です。

クラス、メソッド、属性、カプセル化、データ隠蔽、継承、ポリモーフィズム、抽象化をサポートします...?

理論的な意味を無視すると、次のようになります。

「「クラス」というキーワードを持つ言語」 :-P

aib の発言をさらに詳しく説明すると、利用可能な標準ライブラリがオブジェクト指向でない限り、その言語は実際にはオブジェクト指向ではないと言えます。この最大の例は PHP です。標準のオブジェクト指向概念をすべてサポートしていますが、標準ライブラリの大部分がオブジェクト指向ではないという事実は、オブジェクト指向の方法でコードを記述するのがほぼ不可能であることを意味します。

実際の API で名前空間をサポートする言語では、すべての標準ライブラリですべての関数呼び出しに mysql_ や pgsql_ などのプレフィックスを付ける必要がある場合、名前空間が導入されていることは問題ではありません。 mysql_ を作成し、ファイルの先頭に単純な「include system.db.mysql.*」を追加するだけで、それらがどこから来たのかがわかるようになります。

クラスを作ることができれば、それはオブジェクト指向です
例えば ​​:Java はオブジェクト指向ですが、JavaScript はそうではありません。C++ はある種の「オブジェクト指向」言語のように見えます。

私の経験では、言語はオブジェクト指向ではありませんが、コードはオブジェクト指向です。

数年前、オブジェクト指向の機能を理解し始めたとき、私は AppleScript で一連のプログラムを作成していましたが、実際にはオブジェクト指向機能を強制していませんでした。AppleScript でオブジェクトを記述するのは不器用ですが、時間をかけて方法を理解すれば、クラスやコンストラクタなどを作成することは可能です。

言語はドメインの正しい言語でした。Macintosh 上のさまざまなプログラムを連携させて、入力ファイルに基づいていくつかの自動タスクを実行します。わざわざオブジェクト指向スタイルを自己強制することは、正しいプログラミングの選択でした。その結果、コードのトラブルシューティング、テスト、理解が容易になるからです。

コードを手続き型から OO に変更する際に私が最も注目した機能は、カプセル化でした。プロパティとメソッド呼び出しの両方。

シンプル:(保険の特徴を比較)

1-ポリモーフィズム2インヒャー材3包カプセーション4-Re-use。:)

物体:オブジェクトはデータのリポジトリです。たとえば、MyList が ShoppingList オブジェクトの場合、MyList はショッピング リストを記録する可能性があります。

クラス:クラスはオブジェクトのタイプです。同じクラスのオブジェクトが多数存在する可能性があります。たとえば、MyList と YourList は両方とも ShoppingList オブジェクトである可能性があります。

方法:オブジェクトまたはクラスを操作するプロシージャまたは関数。メソッドは特定のクラスに関連付けられます。たとえば、addItem は、ShoppingList オブジェクトに項目を追加するメソッドである可能性があります。メソッドがクラスのファミリーに関連付けられる場合があります。たとえば、addItem は任意のリストに対して動作する可能性がありますが、ShoppingList はその 1 つのタイプにすぎません。

継承:クラスは、より一般的なクラスからプロパティを継承する場合があります。たとえば、ShoppingList クラスは、List クラスから一連の項目を格納するプロパティを継承します。

多態性:オブジェクトの複数の異なるクラスで、それらのクラスがメソッド呼び出しの異なる実装を必要とする場合でも、1 つのメソッド呼び出しを機能させることができます。たとえば、ShoppingList への項目の追加は、ShoppingCart への項目の追加とはまったく異なりますが、1 行のコードであらゆる種類の List に対して「addItem」メソッドを呼び出すことができる場合があります。

オブジェクト指向:各オブジェクトは、それ自体のクラスと、どのメソッドがそのクラス内のオブジェクトを操作するかを知っています。各 ShoppingList と各 ShoppingCart は、addItem のどの実装が適用されるかを知っています。

このリストの中で、オブジェクト指向言語と手続き型言語 (C、Fortran、Basic、Pascal) を真に区別する 1 つの点は、ポリモーフィズムです。

ソース: https://www.youtube.com/watch?v=mFPmKGIrQs4&list=PL-XXv-cvA_iAlnI-BQr9hjqADPBtujFJd

これを皆さんと共有できることを嬉しく思います。非常に興味深く、私にとって役に立ちました。これは、スティーブ (プログラマーではありません) が OOP を簡単に説明した 1994 年のローリングストーン誌のインタビューからの抜粋です。

ジェフ・グッデル:オブジェクト指向ソフトウェアとは何なのか、簡単に説明してもらえますか?

スティーブ・ジョブズ:物体は人間と同じです。彼らは生きていて、物事を行う方法についての知識を内部に持ち、物事を思い出すことができるように内部に記憶を持っているものを呼吸しています。そして、非常に低いレベルで彼らと対話するのではなく、私たちがここで行っているように、非常に高い抽象レベルで彼らと対話します。

以下に例を示します。私があなたの洗濯物のオブジェクトなら、あなたは私にあなたの汚い服を与えて、「あなたは私の服を洗濯してもらえますか」というメッセージを私に送ることができます。私はたまたまサンフランシスコで最高の洗濯場所がどこにあるかを知っています。そして私は英語を話します、そしてポケットにはドルを持っています。それで私は外に出てタクシーを拾い、運転手にサンフランシスコのこの場所まで連れて行ってくれと言いました。あなたの服を洗濯しに行き、タクシーに飛び乗り、ここに戻ります。私はあなたのきれいな服を渡して、「これがあなたのきれいな服です」と言います。

私がどうやってそんなことをしたのか、あなたには分からないでしょう。あなたは洗濯場の知識がありません。フランス語が話せるのに、タクシーを拾うこともできないかもしれません。ポケットにドルがないので、お金を支払うことはできません。それでも、私はそれをすべて行う方法を知っていました。そして、それを何も知る必要はありませんでした。その複雑さはすべて私の中に隠されており、私たちは非常に高い抽象レベルで対話することができました。それがオブジェクトというものです。これらは複雑さをカプセル化しており、その複雑さへのインターフェイスは高レベルです。

原型

現実世界のシナリオをコードで表現する機能。

foreach(House house in location.Houses)
{
 foreach(Deliverable mail in new Mailbag(new Deliverable[]
              {
              GetLetters(), 
              GetPackages(), 
              GetAdvertisingJunk()
              })
 {
    if(mail.AddressedTo(house))
    {
        house.Deliver(mail);
    }
 }
}

-

foreach(Deliverable myMail in GetMail())
{
    IReadable readable = myMail as IReadable;
    if ( readable != null )
    {
        Console.WriteLine(readable.Text);
    }
}

なぜ?

これをより簡単に理解できるようにするためです。これは私たちの頭の中でより理にかなっており、正しく実装されていれば、コードがより効率的で再利用可能になり、繰り返しが減ります。

これを達成するには、次のものが必要です。

  • ポインタ/リファレンス this == this および this != that であることを確認するため。
  • クラス を指す(例:データ (int Hairyness) と操作 (Throw(IThrowable)) を保存する Arm)
  • ポリモーフィズム (継承および/またはインターフェース) 特定のオブジェクトを一般的な方法で処理して、本を読んだり、壁に落書きしたりできるようにします (どちらも IReadable を実装しています)
  • カプセル化 リンゴは Atoms[] プロパティを公開しないため
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top