2

クラス Parent があり、子が Child1 と Child2 であるとします。

Parent+ParentCategory を宣言してから、メソッドを宣言します。

-(void) Redraw;

後で、Child1 のRedraw機能を Child2 の機能とは異なるものにしたいと考えていますRedraw

Child1+Child1Category を宣言してからオーバーライドできますか

-(void) Redraw

Child1-(void)Redrawの親カテゴリで関数を呼び出すことができますか?

それはできますか?

良いアプローチは何ですか?

クラスは互いに継承できることを知っています。プロトコルは互いに拡張できることを知っています。なぜカテゴリがそうでないのだろうか?

4

3 に答える 3

4

私は与えられた答えに同意しません:

A.: カテゴリのメソッドがクラスのメソッドに勝つというのは正しくありません。これは実装の詳細ですが、動作は定義されていません。

カテゴリで宣言されたメソッドの名前が、元のクラスのメソッド、または同じクラス (またはスーパークラス) の別のカテゴリのメソッドと同じである場合、どのメソッド実装が使用されるかについての動作は未定義です。ランタイム。

B.しかし、これは問題ではありません。クラスで定義されているカテゴリでメソッドを定義することも、2 つの衝突するカテゴリでメソッドを定義することもありません。シット。あなたのケースには当てはまりません。次のようなものに適用されます。

@interface A : NSObject
- (void)doSomething;
@end
@implementation A
- (void)doSomething {}
@end

@interface A (Addition)
- (void)doSomething;
@end
@implementation A (Addition)
- (void)doSomething {}
@end

あなたが正しいと私が理解しているなら、あなたはこれをしたくありません。あなたはそのようなものが欲しい:

ベースレベル:

@interface A : NSObject
@end
@implementation A
@end

@interface A (Addition)
- (void)doSomething;
@end
@implementation A (Addition)
- (void)doSomething {}
@end

クラスにあるカテゴリにメソッドがないため、これはルールに違反しません。

サブクラス レベル:

@interface B : A
@end
@implementation B
@end

@interface B (Addition)
- (void)doSomething;
@end
@implementation B (Addition)
- (void)doSomething {}
@end
  1. A のレベルに干渉がないのと同じ理由で、B のレベルに干渉はありません。

  2. B は A から -doSomething を継承するため、衝突があると言う人もいるかもしれません。しかし、これは衝突ではありません。なぜなら、この場合、優先規則が適用されるからです。サブクラスはメソッドを上書きします。

出来るよ。

編集:

メソッドをクラスに追加するだけで問題を確認できます。それはコンパイルされますか?衝突の場合、そうではありません。あなたの場合、そうなるでしょう。

于 2013-06-07T22:06:12.767 に答える
2

シットでリプレイします。この答えから:

このように言いましょう。カテゴリ、ピリオド、エバー、回答の終わりを使用してメソッドをオーバーライドしないでください。

この理由は、カテゴリのメソッドが常にクラス メソッドに勝つことは正確にわかっていますが (つまり、クラスで既に宣言されているカテゴリにメソッドを実装する場合、カテゴリで拡張しているカテゴリのメソッドです)。が呼び出されます。)実装が優先される同じメソッドを実装する複数のカテゴリがある場合は未定義です

于 2013-06-07T09:56:46.397 に答える
0

これを行うためにカテゴリを使用するのは賢明ではありません。カテゴリは、現在のクラスにメソッドを追加します。同じ名前のメソッドが複数ある場合は、古いメソッドが置き換えられます (オーバーライドではありません)。しかし、残念ながら、どちらが置き換えられるかはわかりません。トラブルの原因となりますので、絶対にしないでください。

また、おそらく子カテゴリから親のメソッドを呼び出すことはできません。ここで最も適切な設計はプロトコルです。

于 2013-06-07T10:01:30.250 に答える