كيفية إلقاء "فئة A" إلى الفئة الفرعية "الفئة B" - الهدف-ج

StackOverflow https://stackoverflow.com/questions/1236434

سؤال

أنا أستخدم إطارا يحدد ويستخدم "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" ولن يستجيب لأي طريقة "الكلمة".

لست متأكدا من هذا ممكن ... أي شخص يعرف ماذا أفعل الخطأ هنا؟

لقد وجدت وظيفة مماثلة وهو مقنع تماما لما أطلبه هنا

هل كانت مفيدة؟

المحلول

عادة ما تكون متغيرات كائن الصب في الهدف - C خطأ (هناك بعض الحالات التي يكون فيها صواب، ولكن أبدا لهذا النوع من الأشياء). لاحظ أنك لا تضع كائن - أنت صب مؤشر إلى كائن. ثم لديك مؤشر النوع ClassB*, ، ولكن لا يزال يشير إلى نفس مثيل الفصل. وأشار الشيء إلى أنه لم يتغير على الإطلاق.

إذا كنت ترغب حقا في تحويل مثيلات Classa إلى ClassB، فستحتاج إلى كتابة طريقة منشئتها من الفئة التي يمكنها إنشاء مثيل ClassB من Classa. إذا كنت بحاجة فعلا إلى إضافة متغيرات مثيل، فقد يكون هذا خيارك الأفضل.

كما قال جايسون، رغم ذلك، فمن الأفضل في كثير من الأحيان تجربة فئة أولا.

نصائح أخرى

لا يمكنك إلقاء فئة فائقة فقط على الفئة الفرعية. لا ينفذ في الواقع أي من المتغيرات / الخصائص أو الأساليب الإضافية الخاصة بك. بمجرد محاولة إرسالها باستخدام طريقة تعرفها على الفئة الفرعية الخاصة بك، ستحصل على استثناء وقت التشغيل وسيتم إنهاء طلبك. يمكنك فقط طرحها بأمان في اتجاه واحد: من أكثر تحديدا إلى أكثر عمومية. أي، يمكنك إلقاء ككلاتنا إلى الفصل الدراسي بأمان، باستخدام طرق وخصائص Classa فقط، ولكن ليس في الاتجاه الآخر.

فكر في الأمر بهذه الطريقة: لديك سيارة (الطبقة الأصل) و fourdoorsedan (الفئة الفرعية). كل سيارة لديها محرك واثنين من الأبواب. الآن، دعنا نقول أنك تحصل على سيارة من مكان ما، وهذا هو حقا كل ما تعرفه عنه. أنت تخبر المشغل، أن السيارة هي رباعية فوردوزيدان، ولكن في الواقع اتضح أنها ليست كذلك. لذلك عندما يفعل المشغل شيئا مثل: openbackpassengerdoor، ماذا يحدث؟ هناك اثنين فقط من الأبواب! هو نفسه هنا.

إذا كنت ترغب فقط في إضافة وظيفة صغيرة إلى Classa، فستتمكن من فئات الهدف - C، فربما ما تريد ولن يتم طلب أي صب. اقرأ الوثائق بعناية، ومع ذلك، لأنهم ليسوا دون تحذيرهم.

إذا كنت ترغب فقط في إضافة طريقة إلى الكائنات الموجودة، فهو الفئة الفرعية ليست الطريقة الصحيحة. يمكنك إضافة طريقة إلى الفئات الموجودة (وحالاتها) باستخدام ميزة لغة تسمى الفئة.

مثال:

//"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 مجاني وخسر مع أنواع، لا تحتاج حتى معرفة النوع قبل اليد، على سبيل المثال. يمكنك تغيير جميع مراجع كلصتك إلى الهوية. أعلم أنه أكثر أمانا لمعرفة أن لديك النوع المتوقع ولكن إذا كان رمزك صحيحا لا يهم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top