銀行の「口座」の抽象化を提供したいとします。 Pythonでfunction
オブジェクトを使用する1つの方法を次に示します。
def account():
"""Return a dispatch dictionary representing a bank account.
>>> a = account()
>>> a['deposit'](100)
100
>>> a['withdraw'](90)
10
>>> a['withdraw'](90)
'Insufficient funds'
>>> a['balance']
10
"""
def withdraw(amount):
if amount > dispatch['balance']:
return 'Insufficient funds'
dispatch['balance'] -= amount
return dispatch['balance']
def deposit(amount):
dispatch['balance'] += amount
return dispatch['balance']
dispatch = {'balance': 0,
'withdraw': withdraw,
'deposit': deposit}
return dispatch
型の抽象化(つまり、Pythonのclass
キーワード)を使用した別のアプローチを次に示します。
class Account(object):
"""A bank account has a balance and an account holder.
>>> a = Account('John')
>>> a.deposit(100)
100
>>> a.withdraw(90)
10
>>> a.withdraw(90)
'Insufficient funds'
>>> a.balance
10
"""
def __init__(self, account_holder):
self.balance = 0
self.holder = account_holder
def deposit(self, amount):
"""Add amount to balance."""
self.balance = self.balance + amount
return self.balance
def withdraw(self, amount):
"""Subtract amount from balance if funds are available."""
if amount > self.balance:
return 'Insufficient funds'
self.balance = self.balance - amount
return self.balance
私の先生はclass
キーワードを導入してトピック「オブジェクト指向プログラミング」を開始し、次の箇条書きを示しました。
オブジェクト指向プログラミング
モジュール式プログラムを編成する方法:
- 抽象化の障壁
- メッセージパッシング
- 情報と関連する動作をまとめる
上記の定義を満たすには、最初のアプローチで十分だと思いますか?はいの場合、オブジェクト指向プログラミングを行うためにclass
キーワードが必要なのはなぜですか?
おめでとう!特定のプログラミング言語のサポートなしでオブジェクト指向を実行できるというよく知られた事実を再発見しました。基本的には、Schemeでオブジェクトが この古典的なテキストブック に導入される方法と同じです。 Schemeにはclass
キーワードまたは同等のキーワードがなく、クラスさえなくてもオブジェクトを作成できることに注意してください。
ただし、オブジェクト指向のパラダイムは非常に成功したため、多くの言語-およびPythonも例外ではありません-組み込みのサポートが提供されています。これは、開発者がパラダイムを使いやすくするためだけですそして、その言語のオブジェクト指向の標準形式を提供します。多くの言語がfor
ループを提供するのは基本的に同じ理由ですが、while
ループを1つだけ使用してエミュレートすることもできますまたは2行の追加コード-単に使いやすさ。
最初の定義は、先生の3つのポイントを満たしていることに同意します。私は何かのためにクラスキーワードを必要とする必要とは思いません。カバーの下では、オブジェクトとは何か他に、データを操作するためのさまざまなタイプのデータと関数を持つデータ構造がありますか?もちろん、関数もデータです。
さらに進んで、オブジェクト指向プログラミングを行うことは、あなたの言語が提供するkeywordsにそれほど依存していないと言い、Cでオブジェクト指向プログラミングを行うことができますあなたがそう望めば!実際、 linuxカーネル はこのような手法を採用しています。
ここでclassキーワードから推測できることは、言語はこの種の構成をそのまま使用できるため、自分で機能を再実装するためにすべてのフープを通過する必要がないということです(これは、自体!)。あなたが得るかもしれないすべての構文糖は言うまでもありません。
もちろんできます!
セルフプログラミング言語は、動的なプロトタイプベースのオブジェクト指向言語であり、すべてがオブジェクトであり、クラスの意味などはまったくありません。オブジェクトを作成する方法のテンプレートとしてクラスを持つのではなく、プロトタイプオブジェクトのアイデアとそれらを複製するアイデアに焦点を当てています。
詳細は http://www.selflanguage.org/ を確認してください。とても興味深いと思います。OOPが好きな場合は、それほど一般的ではないものをチェックすることをお勧めします。
常にではない:それは言語に依存します。 Pythonでこれを行う機能を実証しましたが、Pythonタグにもかかわらず、質問が言語に依存しないことを意図している場合)すべての言語で実行できるわけではありませんこれは、たとえばJavaではほとんどできません。mainを含むクラスを無視して、classキーワードなしでmain内で定義されたオブジェクトに任意のメソッド/フィールドを定義する方法はありません。匿名クラスは存在しますが、インターフェースとインターフェースで定義されたものを除いて、パブリックメンバーを持つことはできません。カスタムインターフェースを定義して匿名クラスを作成することは可能ですが、これは単にクラスを使用する場合と同じです(ただし便利ではありません)。
Doc Brownは素晴らしい答えを持っていますが、私がしようとしているポイントは、あなたのソリューションをまったく許可しない言語が少なくとも1つあると確信しているということです。
先生の定義は、オブジェクト指向プログラミングの最も重要なポイントを完全に見逃しています。 「メッセージパッシング」は、Smalltalkの人々が思い描いた無意味なものであり、試行錯誤の末に失敗しました。 OOPの真の力はLiskov置換として知られているものであり、概念は説明および理解がかなり簡単ですが、基本的な実装は本質的に不可能であるほど複雑です言語レベルのサポートなしで正しく行うため。
Liskov置換の考え方は、コードが特定の型の変数を予期している場所であればどこでも、その型から派生した任意の型を受け入れ、派生型の詳細を知らなくても正しく機能する必要があるということです。
たとえば、GUIフレームワークは至る所でLiskov置換を使用します。それらは、「任意のコントロール」を表すことができる基本Control
クラスを持つ傾向があり、これは描画、サイズ変更、ユーザー入力への応答などの基本的なアクションを認識するインターフェースを定義します。コントロールをクリックすると、UIフレームワークは、そのコントロールの種類を気にすることなく、コントロールのClick
メソッドを呼び出し、コントロールに適切な方法でクリックを処理させます。クラス。 Button
コントロールは、クリックすると、TextBox
コントロールとはまったく異なる処理を実行して、例を1つだけ示します。
したがって、はい、上記の入れ子関数のトリックを使用してオブジェクトに似たものを作成できますが、そのようにして継承とLiskov置換を取得できないため、真のOOPの非常に限定的な代用になります。