意味のある用語のない議論は無意味なので、私は部屋にいる象を指差して尋ねてみようと思いました:言語を「オブジェクト指向」にする正確な理由は何ですか? ここで教科書的な答えを探しているわけではありませんが、それが何であれ、ドメインでうまく機能するオブジェクト指向言語の経験に基づいたものです。
最初に答えるのに役立つ関連する質問は、次のとおりです。オブジェクト指向言語の原型とは何か、またその理由
意味のある用語のない議論は無意味なので、私は部屋にいる象を指差して尋ねてみようと思いました:言語を「オブジェクト指向」にする正確な理由は何ですか? ここで教科書的な答えを探しているわけではありませんが、それが何であれ、ドメインでうまく機能するオブジェクト指向言語の経験に基づいたものです。
最初に答えるのに役立つ関連する質問は、次のとおりです。オブジェクト指向言語の原型とは何か、またその理由
オブジェクト指向の定義はもちろんワームの巨大な缶ですが、ここに私の2セントがあります:
私にとって、オブジェクト指向とは、メッセージを送信することによって連携するオブジェクトに関するものです。つまり、私にとって、オブジェクト指向言語の最も重要な特徴は1つだけです。
オブジェクト指向言語が持つ必要のあるすべての機能の順序付きリストを作成する必要がある場合、次のようになります。
明らかに、このリストは、 Java、C#、C ++など、オブジェクト指向と広く見なされている多種多様な言語を除外しているため、非常に物議を醸しています。これらはすべて、ポイント1、2、3に違反しています。ただし、間違いありません。それらの言語はオブジェクト指向プログラミングを可能にし(しかしCもそうします)そしてそれを容易にします(Cはそうしません)。それで、私はそれらの要件を満たす言語を「純粋にオブジェクト指向」と呼ぶようになりました。
典型的なオブジェクト指向言語として、私はSelfとNewspeakと名付けます。
どちらも上記の要件を満たしています。どちらもSmalltalkに触発され、後継者であり、実際には、ある意味で「もっとOO」になっています。SelfとNewspeakについて私が気に入っているのは、どちらもメッセージ送信パラダイムを極端に取り入れていることです(NewspeakはSelfよりもさらに優れています)。
Newspeakでは、すべてがメッセージ送信です。インスタンス変数、フィールド、属性、定数、クラス名はありません。それらはすべて、ゲッターとセッターを使用してエミュレートされます。
Selfには、クラスはなく、オブジェクトのみがあります。これは、オブジェクト指向が実際に何であるか、つまりクラスではなくオブジェクトを強調しています。
基本的に、オブジェクト指向は「メッセージの受け渡し」に要約されます
手続き型言語では、次のような関数を呼び出します。
f(x)
そして、名前 f はおそらくコンパイル時に特定のコード ブロックにバインドされます。(これが高次関数または関数へのポインターを使用する手続き型言語でない限り、その可能性はしばらく無視しておきましょう。) したがって、このコード行は 1 つの明確なことしか意味しません。
オブジェクト指向言語では、おそらく次のように、メッセージをオブジェクトに渡します。
o.m(x)
この場合。m はコード ブロックの名前ではありませんが、「メソッド セレクター」であり、どのコード ブロックが実際に呼び出されるかは、何らかの方法でオブジェクト o に依存します。このコード行は、o に応じてさまざまな状況でさまざまなことを意味する可能性があるため、よりあいまいまたは一般的です。
大部分の OO 言語では、オブジェクト o に「クラス」があり、クラスによってどのコード ブロックが呼び出されるかが決まります。いくつかの OO 言語 (最も有名なのは Javascript) では、o にはクラスがありませんが、実行時にメソッドが直接関連付けられているか、プロトタイプから継承されています。
私の境界は、言語がオブジェクト指向であるためにクラスも継承も必要ないということです。しかし、この多態的なメッセージの処理は不可欠です。
たとえば C の関数ポインターを使用してこれを偽造することはできますが、C をオブジェクト指向言語と呼ぶには十分ではありません。独自のインフラストラクチャを実装する必要があるからです。あなたはそれを行うことができ、オブジェクト指向スタイルも可能ですが、言語はそれをあなたに与えていません.
Booch によると、次の要素: メジャー:
マイナー:
オブジェクト指向であるのは実際には言語ではなく、コードです。
オブジェクト指向の C コードを (必要に応じて構造体や関数ポインター メンバーを使用して) 記述することは可能であり、そのかなり良い例をいくつか見てきました。(Quake 2/3 SDK が思い浮かびます。) C++ で手続き型 (つまり、オブジェクト指向でない) コードを書くことも間違いなく可能です。
それを考えると、それを「オブジェクト指向言語」にしているのは、言語が優れたオブジェクト指向コードを書くことをサポートしていると言えます。たとえば、通常のメンバー関数に対して、C の構造体で関数ポインター メンバーを使用することに煩わされることは決してありません。したがって、C はオブジェクト指向言語ではないと言えます。
(これを拡張すると、Python はオブジェクト指向ではなく、すべてのステップで必須の「自己」参照とinitと呼ばれるコンストラクターなどがあると言うことができますが、それは宗教的な議論です。)
Simula はしばしば最初の OO 言語として引用されますが、通常、Smalltalk は典型的な OO 言語と見なされます。
現在のオブジェクト指向言語は、概念を最も多く借用している言語によって大まかに分類できます。
これを皆さんと共有できてうれしいです。それは私にとって非常に興味深く、役に立ちました。これは 1994 年の Rolling Stone のインタビューからの抜粋で、Steve (プログラマーではない) が OOP を簡単な言葉で説明しています。
Jeff Goodell: オブジェクト指向ソフトウェアとは何かを簡単に説明していただけますか?
Steve Jobs: 物は人のようなものです。彼らは、物事を行う方法についての知識を内部に持ち、物事を思い出すことができるように内部に記憶を持っているものを呼吸して生きています。非常に低いレベルで対話するのではなく、ここで行っているように、非常に高いレベルの抽象化で対話します。
以下に例を示します。私があなたの洗濯物の対象である場合、あなたの汚れた服を私に渡して、「私の服を洗濯してもらえますか?」というメッセージを送ってください。たまたまサンフランシスコで一番いい洗濯屋がどこにあるか知っています。私は英語を話し、ポケットにはドルを持っています。それで私は外に出てタクシーを呼び、運転手に私をサンフランシスコのこの場所に連れて行ってくれるように言いました。私はあなたの服を洗濯しに行き、タクシーに戻り、ここに戻ります。私はあなたにきれいな服を渡し、「これがあなたのきれいな服です」と言います。</p>
私がどのようにそれをしたかあなたにはわかりません。あなたは洗濯場の知識がありません。たぶんあなたはフランス語を話せますが、タクシーを呼ぶことさえできません。あなたはお金を払うことができません。あなたのポケットにはドルがありません。それでも、私はそのすべてを行う方法を知っていました。そして、あなたはそれを知る必要はありませんでした。その複雑さはすべて私の中に隠されていましたが、私たちは非常に高いレベルの抽象化で対話することができました. それがオブジェクトです。それらは複雑さをカプセル化し、その複雑さへのインターフェースはハイレベルです。
私の知る限り、言語を「オブジェクト指向」にする主な見解は、データのグループ化のアイデアと、そのデータを処理するメソッドをサポートすることです。これは、一般に、クラス、モジュール、継承、ポリモーフィズムなどによって実現されます。
人々が考える(考えた?)オブジェクト指向の意味の概要については、このディスカッションを参照してください。
「典型的な」オブジェクト指向言語に関しては、クリストファーが指摘したように、それは確かにSmalltalkです。
Simples :(保険の性格を比較)
1-ポリモーフィズム2-継承3-カプセル化4-再利用。:)
クラスを作成できる場合、それはオブジェクト指向
です。たとえば、javaはオブジェクト指向であり、javascriptはそうではなく、c++はある種の「オブジェクト指向」言語のように見えます。
私の経験では、言語はオブジェクト指向ではなく、コードはオブジェクト指向です。
数年前、オブジェクト指向の機能を実際には強制しない AppleScript で一連のプログラムを作成していたとき、私は OO を理解し始めました。オブジェクトを AppleScript で記述するのは不器用ですが、時間をかけて方法を理解すれば、クラスやコンストラクタなどを作成することは可能です。
この言語はドメインに適した言語でした。Macintosh でさまざまなプログラムを連携させて、入力ファイルに基づいていくつかの自動タスクを実行しました。トラブルシューティング、テスト、および理解がより簡単なコードが得られるため、オブジェクト指向スタイルを自己強制するために苦労したことは、正しいプログラミングの選択でした。
そのコードを手続き型から OO に変更する際に私が最も気付いた機能は、プロパティとメソッド呼び出しの両方のカプセル化でした。
理論的な含意を無視すると、
「「クラス」と呼ばれるキーワードを持つすべての言語」:-P
aib の発言をさらに進めるために、利用可能な標準ライブラリがオブジェクト指向でない限り、言語は実際にはオブジェクト指向ではないと言えます。これの最大の例は PHP です。すべての標準的なオブジェクト指向の概念をサポートしていますが、標準ライブラリの大部分がオブジェクト指向ではないという事実は、オブジェクト指向の方法でコードを記述することはほとんど不可能であることを意味します。
実際の API で名前空間をサポートする言語では、すべての標準ライブラリですべての関数呼び出しに mysql_ や pgsql_ などのプレフィックスを付ける必要がある場合、それらが名前空間を導入していることは問題ではありません。 mysql_ ファイルの先頭に単純な「include system.db.mysql.*」を追加して、それらがどこから来たのかを知ることができます。
クラス、メソッド、属性、カプセル化、データ隠蔽、継承、ポリモーフィズム、抽象化をサポートしていますか?
アーキタイプ
実際のシナリオをコードで表現する機能。
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);
}
}
なんで?
これをより簡単に理解できるようにするため。それは私たちの頭の中でより理にかなっており、正しく実装されれば、コードはより効率的で再利用可能になり、繰り返しが減ります。
これを実現するには、次のものが必要です。