15

これは昨夜私の注意を引きました。

最新のALT.NET ポッドキャストで、 Scott Bellware が、Ruby とは対照的に、c#、java などの言語について説明しています。「クラス指向」という言葉を選ぶのではなく、真のオブジェクト指向ではありません。彼らはこの違いについて、あまり詳細に触れたり、長所と短所についてあまり議論したりせずに、非常にあいまいな言葉で話します.

ここでの本当の違いは何ですか?「オブジェクト指向」である他の言語は何ですか? かなり面白そうに聞こえましたが、何が足りないかを知るためだけに Ruby を学ぶ必要はありません。

更新:以下の回答のいくつかを読んだ後、人々は一般的に、ダックタイピングへの参照であることに同意しているようです. 私がまだ理解しているかどうかわからないのは、これが最終的にすべてを大きく変えるという主張です. 特に、疎結合で適切な tdd を既に実行している場合は特にそうです。C# ではできない、Ruby でできる素晴らしいことの例を誰かに見せてもらえますか?

4

14 に答える 14

23

オブジェクト指向言語では、オブジェクトは、クラスではなくオブジェクトを定義することによって定義されますが、クラスは、特定の抽象化の特定の定型的な定義に役立つテンプレートを提供できます。たとえば C# などのクラス指向言語では、オブジェクトをクラスで定義する必要があり、これらのテンプレートは通常、実行前に缶詰にしてパッケージ化し、不変にします。オブジェクトは実行前に定義する必要があり、オブジェクトの定義は不変であるというこの恣意的な制約は、オブジェクト指向の概念ではありません。それはクラス指向です。

于 2009-04-27T09:12:11.753 に答える
15

ここでのダックタイピングのコメントは、Ruby と Python がC#よりも動的であるという事実に起因しています。OO の性質とは実際には何の関係もありません。

(私が思うに)Bellware が意味していたのは、Ruby ではすべてがオブジェクトだということです。クラスでさえ。クラス定義は、オブジェクトのインスタンスです。そのため、実行時に動作を追加/変更/削除できます。

もう 1 つの良い例は、NULL もオブジェクトであるということです。Ruby では、すべてが文字通りオブジェクトです。そのような深い OO を全体に持つことで、method_missing などの楽しいメタプログラミング手法が可能になります。

于 2008-09-09T15:19:32.663 に答える
10

IMO、それは本当に「オブジェクト指向」を過度に定義していますが、彼らが言及しているのは、C#、C++、Java などとは異なり、Ruby はクラスの定義を使用しないということです。実際には、オブジェクトを直接操作するだけです。 . 逆に、たとえば C# では、 new キーワードを使用してオブジェクトにインスタンス化する必要があるクラスを定義します。重要な点は、C# でクラスを宣言するか、それを記述しなければならないということです。さらに、Ruby では、すべて(偶数など) がオブジェクトです。対照的に、C# はオブジェクト型と値型の概念を保持しています。実際、これは、C# や他の同様の言語 (オブジェクトの型と値) について彼らが指摘していることを示していると思います。typeシステムを意味します。つまり、オブジェクトを操作するだけでなく、型を記述するシステム全体があることを意味します。

概念的には、OO設計は、最近のソフトウェア システムの複雑さに対処するための抽象化を提供するものだと思います。この言語は、オブジェクト指向設計を実装するために使用するツールです。オブジェクト指向設計をより自然にするものもあります。私は、より一般的でより広い定義から、C# などは依然としてオブジェクト指向言語であると主張します。

于 2008-09-09T15:20:03.083 に答える
9

OOP には 3 つの柱があります

  1. カプセル化
  2. 継承
  3. ポリモーフィズム

言語がこれら 3 つのことを実行できる場合、それは OOP 言語です。

言語 X の議論は、言語 A が永遠に続くよりも OOP の方が優れていると確信しています。

于 2008-09-09T15:16:47.847 に答える
4

OO はメッセージ指向と定義されることもあります。メソッド呼び出し (またはプロパティ アクセス) は、実際には別のオブジェクトに送信されるメッセージであるという考え方です。受信オブジェクトがメッセージを処理する方法は、完全にカプセル化されています。多くの場合、メッセージは実行されるメソッドに対応しますが、それは単なる実装の詳細です。たとえば、メッセージ内のメソッド名に関係なく実行されるキャッチオール ハンドラーを作成できます。

C# のような静的 OO には、この種のカプセル化はありません。メッセージ既存のメソッドまたはプロパティに対応している必要があります。対応していない場合、コンパイラは文句を言います。ただし、Smalltalk、Ruby、Python などの動的言語は、「メッセージベース」のオブジェクト指向をサポートしています。

したがって、この意味で、C# やその他の静的に型付けされた OO 言語は、真の OO ではありません。つまり、「真の」カプセル化が欠けているからです。

于 2008-10-17T12:28:46.033 に答える
3

更新: その新しい波..これまで私たちが行ってきたすべてが時代遅れであることを示唆しています..ポッドキャストや本でかなり支持されているようです..多分これはあなたが聞いたことです.

これまで、静的クラスに関心があり、オブジェクト指向開発の力を解き放っていませんでした。私たちは「クラスベースの開発」を行ってきました。クラスは、オブジェクトを作成するための固定/静的テンプレートです。クラスのすべてのオブジェクトは同等に作成されます。

たとえば、私が口論していたことを説明するために... PragProg スクリーンキャストから Ruby コードのスニペットを借りさせてください。「プロトタイプベースの開発」は、オブジェクトとクラスの境界をあいまいにします..違いはありません。

animal = Object.new                  # create a new instance of base Object

def animal.number_of_feet=(feet)     # adding new methods to an Object instance. What?
  @number_of_feet = feet
end
def animal.number_of_feet
  @number_of_feet
end

cat = animal.clone          #inherits 'number_of_feet' behavior from animal
cat.number_of_feet = 4

felix = cat.clone           #inherits state of '4' and behavior from cat
puts felix.number_of_feet   # outputs 4

アイデアは、従来のクラスベースの継承よりも状態と動作を継承する強力な方法です。これにより、特定の「特別な」シナリオ (私にはまだ理解できていません) での柔軟性と制御が向上します。これにより、Mix-in (クラスを継承せずに動作を再利用する) のようなことが可能になります。

私たちが問題についてどのように考えるかという基本的なプリミティブに挑戦することによって、「真の OOP」はある意味で「マトリックス」のようなものです...あなたはループで WTF を続けます。このように..コンテナの基本クラスは、生成された乱数が0.5のどちら側であるかに基づいて、配列またはハッシュのいずれかになります。

class Container < (rand < 0.5 ? Array : Hash)
end

Ruby、javascript、そして新しい旅団がこれを開拓しているようです。私はまだこれに取り組んでいます... 読んで、この新しい現象を理解しようとしています. 強力なようです.. あまりにも強力です.. 役に立ちますか? もう少し目を開ける必要があります。興味深い時代..これら。

于 2008-09-18T15:07:22.537 に答える
2

たぶん、ダックタイピングとクラス階層の違いをほのめかしているのでしょうか?

アヒルのように歩き、アヒルのように鳴く場合は、アヒルのふりをして蹴ります。

C# や Java などでは、コンパイラは次のことについて大騒ぎします。そのオブジェクトに対してこの操作を実行することは許可されていますか?

したがって、オブジェクト指向とクラス指向は、次のことを意味する可能性があります。言語はオブジェクトまたはクラスを気にしますか?

__iter__()例: Python では、反復可能なオブジェクトを実装するには、 という名前のメソッドを持つオブジェクトを返すメソッドを提供するだけで済みますnext()。それだけです。インターフェイスの実装はありません (そのようなものはありません)。サブクラス化なし。アヒル/イテレータのように話しているだけです。

編集:すべてを書き直しながら、この投稿に賛成票が投じられました。すみません、二度とやりません。元のコンテンツには、できるだけ多くの言語を学び、言語の医師が言語についてどう考えているか、または何を言っているかについて心配する必要がないというアドバイスが含まれていました。

于 2008-09-09T15:07:09.650 に答える
2

あなたの質問のきっかけとなったポッドキャストの最初の 6 ~ 7 分しか聞いていません。彼らの意図が、C# は純粋なオブジェクト指向言語ではないと言うことである場合、それは実際には正しいです。C# のすべてがオブジェクトではありません (少なくともプリミティブはオブジェクトではありませんが、ボクシングは同じ値を含むオブジェクトを作成します)。Ruby では、すべてがオブジェクトです。Daren と Ben は、"ダックタイピング" の議論ですべての基礎をカバーしているように見えるので、繰り返しません。

この違い (オブジェクトのすべてとオブジェクト以外のすべて) が重要/重要であるかどうかは、Ruby を C# と比較するのに十分な深さがないため、すぐに答えることはできません。ここで Smalltalk を知っている人 (私は知りませんが、知っていればよかったのですが) は、Ruby が 30 年前に最初の純粋な OO 言語であったことから、Ruby の動きを面白がって見ていることでしょう。

于 2008-09-09T15:32:58.557 に答える
1

それは確かに抽象的なポッドキャストでした!
しかし、私には彼らが何をしようとしているのかが分かります。彼らは Ruby Sparkle に目がくらんだだけです。Ruby を使用すると、C ベースや Java のプログラマーが考えもつかないようなことを実行できます。これらの組み合わせにより、夢にも思わない可能性を実現できます。組み込みの String クラスに新しいメソッドを追加したり、名前のないコード ブロックを他のユーザーが実行できるように渡したり、mixin を実行したり…従来の人々は、オブジェクトがクラス テンプレートから離れすぎて変更されることに慣れていません。確かにそこにはまったく新しい世界があります..

C# の連中が十分にオブジェクト指向ではないことについては... 心に留めないでください。Ruby はほとんどの人にそれを行います。
この 10 年間で学ぶべき言語を 1 つだけお勧めするとしたら、それは Ruby です。私はやってよかった..一部の人々はPythonを主張するかもしれませんが. しかし、それは私の意見のようです..男!:D

于 2008-09-09T15:53:29.693 に答える
1

あなたは尋ねました:「誰かが、私がルビーでできて、c# ではできず、この異なる oop アプローチを例示する素晴らしいことの例を見せてくれませんか?」

1 つの良い例は、Rails に組み込まれた ORM である Active Record です。モデル クラスは、データベース スキーマに基づいて実行時に動的に構築されます。

于 2010-07-12T01:56:02.397 に答える
1

オブジェクト指向は概念です。この概念は、特定のアイデアに基づいています。これらのアイデアの技術的な名前 (実際には時間の経過とともに進化し、最初の 1 時間からは存在しなかった原則) は既に上で与えられているので、それらを繰り返すつもりはありません。私はむしろ、これをできる限り単純かつ非技術的に説明しています。

オブジェクト指向プログラミングの考え方は、オブジェクトがあるということです。オブジェクトは小さな独立したエンティティです。これらのエンティティには、情報が埋め込まれている場合と含まれていない場合があります。彼らがそのような情報を持っている場合、エンティティ自体だけがそれにアクセスしたり変更したりできます。エンティティは、相互にメッセージを送信することで相互に通信します。これを人間と比べてみてください。人間は独立した存在であり、内部データを脳に保存し、通信することで相互に作用します (例: 会話)。他の誰かの脳からの知識が必要な場合、直接アクセスすることはできません。その人に質問をする必要があります。

そして、それは基本的にそれです。これは、オブジェクト指向プログラミングの背後にある本当のアイデアです。これらのエンティティを記述し、それらの間の通信を定義し、それらを相互に作用させてアプリケーションを形成します。この概念はどの言語にも限定されません。これは単なる概念であり、C#、Java、または Ruby でコードを作成する場合、それは重要ではありません。いくつかの追加作業を行うと、この概念は純粋な C で実行することもできます。これは関数型言語ですが、概念に必要なすべてを提供します。

現在、さまざまな言語がこの OO プログラミングの概念を採用しており、もちろん、概念が常に同じというわけではありません。たとえば、一部の言語では、他の言語で禁止されていることを許可しています。関連する概念の 1 つに、クラスの概念があります。クラスがある言語もあれば、ない言語もあります。クラスは、オブジェクトがどのように見えるかの青写真です。オブジェクトの内部データストレージを定義し、オブジェクトが理解できるメッセージを定義し、継承がある場合 ( OO プログラミングでは必須ではありません!)、クラスは他のクラス (多重継承が許可されている場合はクラス) も定義します。このクラスは継承します (選択的継承が存在する場合はどのプロパティも継承します)。このような設計図を作成すると、この設計図に従って無制限の量のオブジェクト ビルドを生成できるようになります。

ただし、クラスを持たないオブジェクト指向言語もあります。オブジェクトはどのように構築されますか? まあ、通常は動的です。たとえば、新しい空のオブジェクトを作成し、インスタンス変数やメソッド (メッセージ) などの内部構造を動的に追加できます。または、既存のオブジェクトをそのすべてのプロパティとともに複製してから、変更することもできます。または、2 つのオブジェクトを新しいオブジェクトにマージすることもできます。クラスベースの言語とは異なり、これらの言語は非常に動的です。開発者がコードを書き始めたときに考えもしなかった方法で、実行時にオブジェクトを動的に生成できるからです。

通常、この動的要素には代償があります。言語が動的になるほど、メモリ (RAM) オブジェクトが浪費され、すべてが遅くなります。プログラム フローも非常に動的であり、機会がなければコンパイラが効果的なコードを生成するのは難しいためです。コードまたはデータ フローを予測します。JIT コンパイラーは、プログラム フローを理解すると、実行時にその一部を最適化できますが、これらの言語は非常に動的であるため、プログラム フローはいつでも変更される可能性があり、JIT はすべてのコンパイル結果を破棄して同じコードを再コンパイルする必要があります。何度も何度も。

しかし、これは小さな実装の詳細であり、基本的なオブジェクト指向の原則とは何の関係もありません。オブジェクトが動的である必要がある、または実行時に変更可能でなければならないということはどこにもありません。ウィキペディアはそれをかなりうまく言っています:

プログラミング技術には、情報の隠蔽、データの抽象化、カプセル化、モジュール性、ポリモーフィズム、継承などの機能が含まれる場合があります。

http://en.wikipedia.org/wiki/オブジェクト指向プログラミング

そうかもしれないし、そうでないかもしれない。これはすべて必須ではありません。必須なのは、オブジェクトの存在と、それらが相互に対話する方法を持っていることだけです (そうでなければ、相互に対話できないオブジェクトはほとんど役に立たないでしょう)。

于 2009-06-17T14:42:17.877 に答える
1

これは特にダックタイピングに関するものではないと思います。たとえば、C# は制限付きのダックタイピングを既にサポートしています。たとえば、MoveNext と Current を実装する任意のクラスで foreach を使用できます。

ダックタイピングの概念は、Java や C# などの静的に型付けされた言語と互換性があり、基本的にはリフレクションの拡張です。

これは、静的型付けと動的型付けの場合です。そのようなことがある限り、どちらも適切なOOです。学界の外では、議論する価値はありません。

ごみのコードはどちらでも記述できます。優れたコードはどちらでも記述できます。あるモデルで実行できて、他のモデルで実行できない機能はまったくありません。

本当の違いは、行われるコーディングの性質にあります。静的型は自由を減らしますが、利点は、誰もが自分が何を扱っているかを知っていることです。その場でインスタンスを変更する機会は非常に強力ですが、代償として、何を扱っているかを知ることが難しくなります。

たとえば、Java や C# の場合、IntelliSense は簡単です。IDE は可能性のあるドロップ リストをすばやく作成できます。Javascript や Ruby の場合、これは非常に難しくなります。

たとえば、他の誰かがコーディングする API を作成するなど、特定のことについては、静的型付けに真の利点があります。プロトタイプを迅速に作成するなど、その他の場合、利点はダイナミックになります。

スキル ツールボックスで両方を理解することは価値がありますが、実際に使用しているスキルを深く理解することほど重要ではありません。

于 2008-10-17T12:09:48.570 に答える
0

これはおそらく、C# と Java が OOP をサポートするのではなく、C# と Java で他の人が行っていることを、これらの人々が見ていることに帰着しているのでしょう。ほとんどの言語は、さまざまなプログラミング パラダイムで使用できます。たとえば、C# とスキームで手続き型コードを記述し、Java で関数型プログラミングを行うことができます。それは、あなたがやろうとしていることと、言語が何をサポートしているかについてです。

于 2008-09-09T15:23:22.043 に答える
0

私はこれを突き刺します。

Python と Ruby はダックタイプです。これらの言語で保守可能なコードを生成するには、ほとんどの場合、テスト駆動開発を使用する必要があります。そのため、巨大なサポート フレームワークを作成することなく、依存関係を簡単にコードに挿入できることが開発者にとって非常に重要です。

依存性注入の成功は、非常に優れたオブジェクト モデルを持つことにかかっています。この 2 つは、同じコインの裏表のようなものです。OOP の使用方法を本当に理解している場合は、依存関係を簡単に注入できる設計をデフォルトで作成する必要があります。

依存性注入は動的型付け言語の方が簡単であるため、Ruby/Python 開発者は、自分の言語が他の静的型付け言語よりもオブジェクト指向の教訓をよく理解していると感じています。

于 2008-09-09T15:13:00.837 に答える