web-dev-qa-db-ja.com

JavaインターフェイスとObjective-Cプロトコルの違いは?

私はJavaを知っていて、現在Objective-Cを学んでいます。 JavaインターフェイスとObjective-Cプロトコルの違いは何ですか?

92
Arne Evertsson

最初に、Javaの作成者の1人からの少し トピックの歴史的観点 について説明します。次に、ウィキペディアには中程度に役立つ Objective-Cプロトコルのセクション があります。特に、Objective-Cはフォーマルプロトコル(Javaインターフェイスに相当する@protocolキーワードで明示的に宣言されている)と非公式プロトコル(クラスによって実装された1つ以上のメソッド。リフレクションを介して検出できます)。

正式なプロトコル( "インターフェイスの実装"のObjective-C用語)を採用すると、Javaで期待されるように、コンパイラは未実装のメソッドに対して警告を発します。 Java(skaffmanとして)とは異なり、Objective-Cクラスが正式なプロトコルに含まれるメソッドを実装する場合、そのプロトコルに「準拠する」と言われ、そのインターフェースが明示的にそれを採用していなくても。 次のように、コードでプロトコルの適合性をテストできます( -conformsToProtocol: を使用)。

if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
    ...
}

注:Appleの ドキュメント 状態:

「このメソッドは、上記のようにヘッダーファイルの正式な宣言のみに基づいて適合性を判断します。プロトコルで宣言されたメソッドが実際に実装されているかどうかはチェックしません。これはプログラマーの責任です。」

Objective-C 2.0(OS X 10.5 "Leopard"およびiOS)では、正式なプロトコルでオプションのメソッドを定義できるようになり、クラスはすべてのプロトコルを実装している限り、プロトコルに準拠します必要なメソッド。 @required(デフォルト)および@optionalキーワードを使用して、mustまたはmayに続くメソッド宣言を切り替えることができますプロトコルに準拠するように実装されます。 (Appleの Objective-C 2.0プログラミング言語 のセクションを参照してください オプションのプロトコルメソッド 。)

オプションのプロトコルメソッドは、特にdelegatesおよびlistenersの実装に関して、開発者に多くの柔軟性をもたらします。 MouseInputAdapter (Javaも単一継承であるため面倒な場合があります)のようなものを拡張したり、多くの無意味な空のメソッドを実装したりする代わりに、プロトコルと気になるオプションのメソッドのみを実装します。このパターンでは、呼び出し元はメソッドを呼び出す前に実装されているかどうかをチェックします( -respondsToSelector を使用)。

if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
    [myObject fillArray:anArray withObject:foo];
    ...
}

リフレクションのオーバーヘッドが問題になる場合は、常に 再利用のためにブール結果をキャッシュ できますが、時期尚早に最適化する衝動に抵抗します。 :-)

81
Quinn Taylor

それらはほとんど同じです。しかし、私を捕らえた1つのことは、Objective CプロトコルがNSObjectも実装することを明示的に宣言しない限り、そのプロトコルへの参照はNSObjectが宣言するメソッドにアクセスしないことです(とにかくコンパイラの警告なしで)。 Javaを使用すると、インターフェイスへの参照を保持し、それに対してtoString()などを呼び出すことができます。

例えば

目標C:

@protocol MyProtocol
// Protocol definition
@end

id <MyProtocol> myProtocol;

 [myProtocol retain] // Compiler warning

Java:

public interface MyInterface {
// interface definition
}

MyInterface myInterface;

myInterface.toString();  // Works fine.

目標C(修正済み):

@protocol MyProtocol <NSObject>
// Protocol definition
@end

id <MyProtocol> myProtocol;

[myProtocol retain] // No Warning
18
Tom Jefferys