26

Java のような静的言語では、インターフェイスが必要です。そうしないと、型システムによって特定のことができなくなるからです。しかし、PHP や Python のような動的言語では、ダックタイピングを利用するだけです。

PHP はインターフェースをサポートしています。Ruby と Python にはそれらがありません。ですから、それらがなくても幸せに暮らせることは明らかです。

私は主に PHP で仕事をしてきましたが、インターフェイスを定義する機能を実際に利用したことはありません。特定の共通インターフェースを実装するための一連のクラスが必要な場合は、それをドキュメントに記述します。

それで、あなたはどう思いますか?動的言語でインターフェイスをまったく使用しないほうがよいのではないでしょうか?

4

17 に答える 17

18

私はそれをより便利なレベルと考えています。「ファイルのような」オブジェクトを取り、その上で read() メソッドを呼び出すだけの関数がある場合、ユーザーにある種の File インターフェイスの実装を強制するのは不便であり、制限さえあります。オブジェクトに読み取りメソッドがあるかどうかを確認するのも簡単です。

ただし、関数が大量のメソッド セットを想定している場合は、オブジェクトがインターフェイスをサポートしているかどうかを確認してから、個々のメソッドのサポートを確認する方が簡単です。

于 2008-09-18T11:16:30.410 に答える
10

はい、ポイントがあります

インターフェイスを明示的に使用しない場合でも、コードはオブジェクトを特定のメソッドを実装しているかのように使用しますが、暗黙のインターフェイスが何であるかは不明です。

インターフェイスを受け入れるように関数を定義すると (PHP で言う)、それは以前に失敗し、問題はメソッドが作業を行うことではなく、呼び出し元にあります。一般的に、早い段階で失敗することは、従うべき良い経験則です。

于 2008-09-18T11:10:52.530 に答える
9

インターフェースは、Java などの静的言語に、ある程度の動的言語のような柔軟性を実際に追加します。これらは、実行時に実装するコントラクトのオブジェクトを照会する方法を提供します。

その概念は、動的言語にうまく移植されます。もちろん、「動的」という言葉の定義によっては、Cocoa でプロトコルをかなり広範に利用する Objective-C も含まれます。

Ruby では、オブジェクトが特定のメソッド名に応答するかどうかを尋ねることができます。しかし、それはあなたが望むことをするというかなり弱い保証です。特に、何度も何度も使用される単語が少ないこと、完全なメソッド署名が考慮されていないことなどを考えると.

Rubyで私は尋ねるかもしれません

object.respond_to? :sync

それで、ええ、それが意味するものは何でも、「同期」という名前のメソッドがあります。

Objective-C では、似たような質問をするかもしれません。つまり、「これは、同期する何かのように見える/歩く/クワックしますか?」:

[myObject respondsToSelector:@selector(sync)]

さらに良いことに、いくらか冗長ではありますが、より具体的な質問をすることができます。つまり、「これは、MobileMe に同期する何かのように見えますか?

[myObject respondsToSelector:@selector(sync:withMobileMeAccount:)]

それは種のレベルまでダックタイピングです。

しかし、MobileMe への同期の実装が約束されているかどうかを実際にオブジェクトに尋ねるには...

[receiver conformsToProtocol:@protocol(MobileMeSynchronization)]

もちろん、プロトコル/ダックの定義と見なす一連のセレクターの存在と、それらが十分に具体的であるかどうかをチェックするだけで、プロトコルを実装できます。どの時点で、プロトコルは醜いresponds_toの大きな塊の単なる省略形ですか? クエリ、およびコンパイラ/IDE が使用するための非常に便利な構文シュガーが含まれています。

インターフェイス/プロトコルは、オブジェクト メタデータの別の次元であり、これらのオブジェクトの処理で動的な動作を実装するために使用できます。Java では、コンパイラはたまたま、通常のメソッド呼び出しに対してそのようなことを要求します。しかし、Ruby、Python、Perl などの動的言語でさえ、「オブジェクトが応答するメソッド」を超えた型の概念を実装しています。したがって、class キーワードです。Javascript は、その概念を持たない唯一の一般的に使用されている言語です。クラスがある場合は、インターフェイスも意味があります。

確かに、ほとんどのアプリケーション コードよりも複雑なライブラリやクラス階層の場合に便利ですが、この概念はどの言語でも役立つと思います。

また、他の誰かがミックスインについて言及しました。Ruby ミックスインは、コードを共有する方法です。たとえば、クラスの実装に関連しています。インターフェイス/プロトコルは、クラスまたはオブジェクトのインターフェイスに関するものです。それらは実際に互いに補完することができます。動作を指定するインターフェイスと、オブジェクトがその動作を実装するのに役立つ 1 つ以上の mixin がある場合があります。

もちろん、両方の言語を明確に第一級の言語機能として備えている言語は考えられません。ミックスインを使用する場合、通常、ミックスインを含めることは、それが実装するインターフェースを意味します。

于 2008-09-18T13:15:11.870 に答える
4

高度なセキュリティ制約がなく (誰もあなたが望まない方法でデータにアクセスすることはありません)、適切なドキュメントや十分に訓練されたコーダーがいる場合 (そのため、インタープリター/コンパイラーが何をすべきかを伝える必要はありません)する)、それではダメです。

ほとんどの中規模のプロジェクトでは、ダックタイピングだけで十分です。

于 2008-09-18T11:46:57.043 に答える
3

Python には interfaces がないという印象を受けました。私が知っている限り、Python は動的言語であるため、コンパイル時に実装するメソッドを強制することはできません。

Python 用のインターフェイス ライブラリがありますが、私はそれらを使用したことがありません。

Python には Mixin もあるため、Mixin を定義して Interface クラスを作成し、passすべてのメソッドの実装に使用することもできますが、それではあまり価値がありません。

于 2008-09-18T11:14:05.267 に答える
3

インターフェイスの使用は、あなたのライブラリを使用する人の数によって決まると思います。それがあなただけの場合、または小さなチームの場合、ドキュメントと規則は問題なく、インターフェイスが必要であることが障害になります。それが公開ライブラリである場合、インターフェースは、人々が単なるヒントではなく正しいメソッドを提供するように制約するため、はるかに便利です。したがって、インターフェイスは公開ライブラリを作成する上で間違いなく価値のある機能であり、動的言語がアプリでより多く使用され、厳密に型指定された言語が大きなライブラリで使用される多くの理由の 1 つは、その欠如 (または少なくとも強調されていないこと) であると思います。

于 2008-09-18T11:39:10.120 に答える
2

Python3000には抽象基本クラスがあります。読む価値があります。

于 2008-09-18T16:11:03.727 に答える
2

存在しないメソッド呼び出しが致命的なエラーを引き起こし、アプリケーション全体をダウンさせる PHP のような言語では、はいインターフェイスが理にかなっています。

無効なメソッド呼び出しをキャッチして処理できる Python のような言語では、そうではありません。

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

Rene さん、ここ StackOverflow の「動的言語で大規模システムを設計するためのベスト プラクティス」の質問に対する私の回答を読んでください。開発の労力を節約し、新しいプログラマーをプロジェクトに導入しやすくするために、動的言語の自由を放棄することのいくつかの利点について説明します。インターフェイスは、適切に使用すると、信頼性の高いソフトウェアを作成するのに大きく貢献します。

于 2008-09-18T11:27:24.830 に答える
1

Java「インターフェース」の用途の 1 つは、Java で厳密に型指定された mixin を許可することです。適切なスーパークラスと、インターフェイスをサポートするために実装された追加のメソッドを組み合わせます。

Python には複数の継承があるため、複数のスーパークラスからのメソッドを許可するためのインターフェイスの工夫は実際には必要ありません。

しかし、私は強力な型付けのいくつかの利点が気に入っています。主に、私は早期エラー検出のファンです。「インターフェースのような」抽象的なスーパークラス定義を使用しようとしています。

class InterfaceLikeThing( object ):
    def __init__( self, arg ):
        self.attr= None
        self.otherAttr= arg
    def aMethod( self ):
        raise NotImplementedError
    def anotherMethod( self ):
        return NotImplemented

これにより、ある意味でインターフェースが形式化されます。期待に一致するサブクラスの絶対的な証拠は提供しません。ただし、サブクラスが必要なメソッドの実装に失敗した場合、単体テストは明らかなNotImplemented戻り値またはNotImplementedError例外で失敗します。

于 2008-09-18T12:41:54.790 に答える
0

たとえば、オブジェクトを内部リストに追加するために、初期メソッドで使用する 1 つまたは 2 つのメソッドを呼び出したときにクラッシュしないようにするのではなく、特定のオブジェクトがインターフェイス全体をサポートしているかどうかを確認する方が確かに簡単です。

ダックタイピングには、インターフェイスの利点がいくつかあります。つまり、どこでも簡単に使用できますが、検出メカニズムはまだありません。

于 2008-09-18T11:15:53.763 に答える
0

必要だと感じた場合は、オブジェクトのメソッド/属性を特定のシグネチャと比較する関数を使用して、一種のインターフェイスを実装できます。非常に基本的な例を次に示します。

file_interface = ('read', 'readline', 'seek')

class InterfaceException(Exception): pass

def implements_interface(obj, interface):
    d = dir(obj)
    for item in interface:
        if item not in d: raise InterfaceException("%s not implemented." % item)
    return True

>>> import StringIO
>>> s = StringIO.StringIO()
>>> implements_interface(s, file_interface)
True
>>> 
>>> fp = open('/tmp/123456.temp', 'a')    
>>> implements_interface(fp, file_interface)
True
>>> fp.close()
>>> 
>>> d = {}
>>> implements_interface(d, file_interface)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in implements_interface
__main__.InterfaceException: read not implemented.

もちろん、それはあまり保証しません。

于 2008-09-19T12:30:25.220 に答える
0

まず第一に、Ruby には Interface がそのままではなく、他の言語からインターフェイスと抽象クラスの両方の長所を何とか取り入れた mixin があります。

インターフェイスの主な目標は、オブジェクトがインターフェイス自体に存在するすべてのメソッドを実装する必要があることを確認することです。

もちろん、インターフェイスは決して必須ではありません。Java でさえ、操作しているオブジェクトの種類がわからない場合に、クラスのみを操作し、リフレクションを使用してメソッドを呼び出すことを想像できますが、エラーが発生しやすいため、推奨されません。多くの方法。

于 2008-09-18T11:04:13.247 に答える
0

他の回答に加えて、Javascript には、指定されたインスタンスが指定されたオブジェクトのプロトタイプ チェーンのどこかにある場合に true を返す instanceof キーワードがあることを指摘したいと思います。

これは、「実装オブジェクト」のプロトタイプ チェーンで「インターフェース オブジェクト」を使用する場合 (どちらも JS にとって単なるオブジェクトです)、instanceof を使用してそれが「実装」されているかどうかを判断できることを意味します。これは強制面では役に立ちませんが、インターフェイスの一般的な用途の 1 つであるポリモーフィズム面では役に立ちます。

MDN instanceof リファレンス

于 2012-12-06T00:49:32.263 に答える
0

動的型付け言語では明示的な型は必要ないと言っているようなものです。すべてを「var」にして、その型を別の場所に文書化してみませんか?

これは、プログラマーによって、プログラマーに課せられる制限です。自分の足を撃ちにくくなります。エラーの余地が少なくなります。

于 2008-09-18T11:37:14.710 に答える
0

PHP プログラマーとしての私の見方では、インターフェイスは基本的にコントラクトとして使用されます。このインターフェイスを使用するものはすべて、特定の関数セットを実装する必要があると言えます。

それだけで役に立つかどうかはわかりませんが、インターフェイスが何であるかを理解しようとするとき、少しつまずきがあることがわかりました。

于 2008-09-18T13:36:52.910 に答える
-2

Java を動的言語で書こうとするのはやめてください。

于 2009-03-27T08:34:10.030 に答える