Objective-Cの継承とは対照的に、カテゴリの実際の使用を理解しようとしています。カテゴリはいつ使うべきですか?実際のコードを使った例が役に立ちます。継承ではなくカテゴリの実際の使用は何ですか?
答えて
私は、クラスのいくつかの既存の関数を上書きするためにサブクラス化する必要なく、既存のクラスに繰り返し使用するいくつかの便利な関数を追加する必要があるときにカテゴリを使用しました。例えば
、私は空の文字列をチェックし、または文字列の先頭と末尾の空白をすべて削除したい:
.hファイル:
@interface NSString (Extension)
-(BOOL)isEmptyString;
-(NSString *)trimLeadingAndTrailingWhiteSpaces;
@end
.mファイル:
@implementation NSString (Extension)
-(BOOL)isEmptyString
{
NSString *myString = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (myString.length == 0)
return TRUE;
else
return FALSE;
}
-(NSString *)trimLeadingAndTrailingWhiteSpaces
{
NSString *myString = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
return myString;
}
@end
それを使用するには、次の
someString = [someString trimLeadingAndTrailingWhiteSpaces];
if ([someString isEmptyString])
{
//someString is empty, do whatever!
}
既存のクラスに機能を追加する必要がある場合。
たとえば、お使いのアプリがNSDate
またはNSString
のインスタンスで動作していて、いくつかの機能を追加したいとします。サブクラスにシステムメソッドを強制的に戻すことはできないので、そのサブクラスに機能を追加することはできません。
ちょうどAPIの例に見て:
1/NSDictionaryのは、ファイルの属性を保持するために使用し、ファイルサイズを返すメソッドを持っています。
2/NSString
には、図面を拡張するUIカテゴリがあります。描画可能な文字列の別のサブクラスを必要としないことに注意してください。すべての文字列に描画する機能が必要です。
スルタンはそれをうまく説明します。ここには、カテゴリーを追加することによってNSStringの機能を拡張するコードexampleがあります。このようにカテゴリを使用すると、実装を持たないクラスをサブクラス化せずに継承することができます。
にメソッドを追加する場合は、カテゴリを使用します。 クラスの既存のメソッドの機能を変更する場合は、サブクラスを作成します。
既存のメソッドを置き換えるためにカテゴリを使用することは可能ですが、サブクラスでオーバーライドするようなものですが、カテゴリを使用しないでください。 3つの理由があります:1)元の方法へのアクセスを失う。 2)既存のコードを破ることはありません。 3)複数のカテゴリが同じメソッドを「オーバーライド」しようとすると、そのクラスが終了するメソッドは未定義です。基本的に、クラスは最後のカテゴリのメソッドをクラスに適用しますが、適用されるカテゴリの順序は信頼できません。それは混乱のためのレシピなので、やってはいけません。
したがって、カテゴリーを使用して、+(NSData*)dataWithCryptographicallyRandomBytes:(NSUInteger)length
または-(void)base64Decode
などのメソッドをNSDataに追加できます。しかし、-writeToFile:atomically:
のような既存のメソッドの動作を変更したい場合は、NSDataのサブクラスを作成し、そこに新しい機能を実装する必要があります。 1つは、オーバーライドで既存の動作を使用したい場合があり、サブクラス化では[super writeToFile:file atmoically:YES]
を呼び出すことで可能になります。また、ここでサブクラスを使用すると、新しい動作が自分のコードにのみ影響することになります。新しい機能が期待できないフレームワーク内のNSDataの使用には影響しません。
カテゴリはJavaインターフェイスに似ています(Javaでは実装はオプションではありません) - メソッドをグループ化してオブジェクトを特定のAPIに応答させる方法で、クラスの種類に依存しません。継承は、追加のivarsを追加する必要があり、新しいクラスがisa関係(student isa person)に一致する必要がある場合には意味があります。いくつかのユーティリティメソッドを追加してもisaの問題は発生しません。これは通常、プロトコルで行われます。カテゴリは、問題のメソッドがオプションである代理人でよく使用されます。
継承によって提供される機能の一部を実現する簡単な方法として、カテゴリを参照しています。継承によって提供されないカテゴリが他にもあります。カテゴリを使用すると、サブクラス化せずに既存のクラスの機能を拡張できます。それらを使用して、クラス内の既存のメソッドを置き換えることもできます。カテゴリメソッドは、元のクラスの子孫を指示するサブクラスとは異なり、既存のクラスに一種のものです。カテゴリメソッドが目的のクラスに追加されると、それはあなたが作成していないクラスを含むクラスのすべてのインスタンスで使用できます。
たとえば、プロジェクトのすべてのデータで使用する必要がある暗号化機能が必要な場合、ほとんどのデータでは保存と操作にNStringのみが使用されます。あなたはそれについて移動できる方法の一つは、NSStringの
NSStringの-Encryption.h
@interface NSString (Encryption)
-(NSString*) encrypt;
@end
NSStringの-Encryption.m
#import "NSString-Encryption.h"
@implementation NSString (Encryption)
-(NSString*) encrypt
{
// your encryption method here
return encryptedString;
}
@end
UseNSString-encryption.mのカテゴリを作成することです
NSString *testString = @"this is test";
NSString *encryptedString = [testString encrypt];
このように、カテゴリはサブクラスよりも使いやすいことがわかります。このメソッドは、NSStringから継承するNSMutableStringからも呼び出すことができます。それは強力です。
カテゴリを使用して、クラスの既存のメソッドを置き換えることもできます。
カテゴリの別の使用法は、プライベートメソッドとして使用することができます。目的は、メソッドの正式なプライベート指定を持たないためです。これは、.hファイルの代わりに.mファイルにカテゴリを入れて行われます。
Phone.h
@interface Phone:NSObject
-(void) call;
@end
Phone.m
@interface Phone(Private)
-(void) validatePhoneEntry:(NSString*) phoneNumber;
@end
@implementation Phone
-(void) validatePhoneEntry:(NSString*) phoneNumber
{
}
-(void) call
{
}
@end
カテゴリの欠点は、あなたがクラスにメンバ変数を追加する必要がある場合は、それらを使用傾けることです。
- 1. 継承は実際にはクラスのメンバーを継承しますか?
- 2. UML - クラス継承、あなたは何を継承しますか?
- 3. C#継承継承でbaseまたはthisを使用する
- 4. 静的メソッド継承と静的変数継承の違いは何ですか?
- 5. CSSでは継承の意味は何ですか?
- 6. フィクスロード処理ではなく、(継承モデル)
- 7. Ruby:継承など何か
- 8. DispatcherObjectの継承と使用法...何が得られないのですか?
- 9. ControllerはGitHubではControllerBaseを継承しますが、VSでは継承しないのはなぜですか?
- 10. は、Androidで継承を正しく使用しています
- 11. JUnit 5 @EnumSourceの実際の使用例は何ですか?
- 12. カレーの実際の使用例は何ですか?
- 13. ビルダーデザインパターンの実際の使用は何ですか?
- 14. minikubeを使用する実際の方法は何ですか?
- 15. StringBufferを使用する実際の例は何ですか?
- 16. Python:ttk.Frameから継承する際にキーワード引数を使用できない
- 17. 基本クラスから継承するものは何ですか?
- 18. 親/子は継承のため、構成の用語は何ですか?
- 19. 公開オブジェクトを継承または使用するのに最適なのは何ですか?
- 20. 抽象クラスとC#での実際のクラス継承
- 21. この継承特有のユースケースは何ですか?
- 22. ステレオタイプとUMLのクラス継承の違いは何ですか?
- 23. javascript継承の正しいプロトタイプの影響は何ですか?
- 24. 実際のラジオ入力ではなく画像を使用する利点は何ですか
- 25. 「生物学」継承のグラフィカル・モデル/シミュレーション(OOP継承ではない)
- 26. 継承するもの! :search_pathsは何ですか?
- 27. javascriptで継承を実装する際のキャッチしないタイプのエラー
- 28. 多重継承の長所と短所は何ですか?
- 29. mixinと継承の違いは何ですか?
- 30. 多重継承の短所は何ですか?
obj-cでは、YES/NOを使用し、TRUE/FALSEを使用しないでください。 – Sulthan
良い点。私はTRUE/FALSEで使用されています。 – user523234
この場合は、とにかく 'return(myString.length == 0)'にする必要があります:) – Sulthan