Objective-Cの - そのサブクラスで「クラスB」から「Aクラス」をキャストする方法
-
11-09-2019 - |
質問
私は「にClassA」、NSObjectののサブクラスを定義し、使用するフレームワークを使用しています。私は「ClassBの」、「にClassA」
のサブクラスを作成したので、自然にいくつかの変数と機能を追加したいと思います今、私の問題はこれです。このフレームワーク内のメソッドの多くは、私は私のサブクラスにキャストしたい「にClassA」のインスタンスを返します。
たとえば、この方法を取るます:
- (ClassA *)doSomethingCool:(int)howCool
今私のコードで私はこれを試してみてください
ClassB * objB;
objB = (ClassB *)doSomethingCool(10);
NSLog(@"objB className = %@", [objB className]);
これはうまく動作します。コンパイルまたは実行時エラーも何もありませんありません。しかし、私には本当に奇妙ですが出力されます:
>> "objB className = ClassA"
キャストは明らかに失敗しました。この時点で起こったものではないことを確認... objBは「ClassBの」として入力されていますが、それはclassNameは「にClassA」であり、それがどんな「ClassBの」メソッドには応答しませんです。
これが可能であるかわからない...誰もが私がここで間違ってやっているか知っている?
私は<のhref = "https://stackoverflow.com/questions/988842/is-it-possible-to-downgrade-an-object-inを求めているものの正反対で同様のポストを見つけました-objective-Cツーその-スーパー ">ここの
解決
Objective-Cでオブジェクト変数をキャストすると、(決してこの種のもののために、それは正しいです、いくつかの例がある)は通常間違いです。あなたがオブジェクトをキャストしていないことに注意してください - あなたは、オブジェクトにのポインタのをキャストしています。その後、型ClassB*
のポインタを持っているが、それはまだにClassAの同じインスタンスを指します。事は全く変わっていないために指摘しています。
、あなたはにClassAからClassBのインスタンスを作成することができClassBのコンストラクタメソッドを記述する必要があります。あなたが本当にインスタンス変数を追加する必要がある場合、これはあなたの最良の選択かもしれません。
ジェイソンが言ったように、しかし、それは最初のカテゴリをしようとするのは良いアイデアがしばしばです。
他のヒント
あなたはそのサブクラスにスーパークラスをキャストすることはできません。それは実際にあなたの追加変数/プロパティやメソッドのいずれかを実装していません。すぐにあなたがあなたのサブクラスで定義する方法と、メッセージにそれを試して、あなたは実行時例外を得ようとしているとアプリケーションが終了する予定です。あなただけ安全に一方向にキャストすることができます:より具体的なから、より一般的に。すなわち、あなただけのメソッドとプロパティにClassAのではなく、他の方法で回避を使用して、安全にClassAに私たちのClassBのをキャストすることができます。
それをこのように考えて:あなたは車(親クラス)とFourDoorSedan(サブクラス)を持っています。すべての車は、エンジンと二つのドアがあります。さて、あなたはどこからか車を取得している、そしてそれは本当にあなたがそれについて知っているすべてだとしましょう。あなたは車がFourDoorSedanですが、実際にはそうでないことが判明し、オペレータに伝えます。オペレータは次のように何かをするときに:openBackPassengerDoor、何が起こりますか? 2つだけのドアがあります!ここは同じです。
あなただけのObjective-Cのカテゴリをチェックして、にClassAに少し機能を追加したい場合は、、彼らはあなたが望むもの、おそらくだと一切キャスティングは必要ありません。彼らは彼らの注意点がないわけではないので、しかし、慎重にドキュメントを読みます。
、サブクラス化は正しい方法ではありません。あなたは<のhref =「http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html」と呼ばれる言語機能を使用して、既存のクラス(およびそのインスタンス)にメソッドを追加することができますREL = "noreferrer">カテゴリでます。
例:
//"ClassA+doSomethingCool.h"
@interface ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool;
@end
//"ClassA+doSomethingCool.m"
@implementation ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool
{
}
@end
鋳造は、オブジェクトの一つのタイプから別のものに変換しません。それはいくつかの工場出荷時のパターンを利用しない限り、あなたは、オブジェクトの種類を変更すると、オブジェクトの別の型を作成するために、いくつかのライブラリを強制することはできません。
はどうなりますか?
ClassB * objB;
objB = (ClassB *)doSomethingCool(10);
[objB subClassMethod];
のObj-Cはかなり自由であり、型を失い、あなたも例えば、手の前にタイプを知る必要はありません。あなたはIDにごClassBの参照のすべてを変更することができます。 私はそれはあなたが期待されるタイプを持っていますが、あなたのコードが正しいかどうかは問題ではないはず知っておくほうが安全です知っています。