سؤال

هل يمكن لأحد أن يشرح لي الفرق بين الفئات والميراث في الهدف ج؟أنا قد قرأت الإدخال في ويكيبيديا والمناقشة حول الفئات هناك لا تبدو مختلفة عن مناقشة الميراث.لقد اطلعت أيضًا على المناقشة حول الموضوع في كتاب "Open iPhone Development" وما زلت لا أفهم ذلك.

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

المحلول

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

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

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

تعد الفئات طريقة رائعة لإضافة وظائف وفي نفس الوقت تتوافق مع مبدأ موجه للكائنات لتفضيل التركيب على الميراث.

تحرير يناير 2012

لقد تغيرت الأمور الآن.باستخدام مترجم LLVM الحالي ووقت التشغيل الحديث 64 بت، يمكنك إضافة iVars وخصائص إلى الفصل ملحقات (وليس الفئات).يتيح لك ذلك إبقاء iVars الخاص خارج الواجهة العامة.ولكن، إذا قمت بتعريف خصائص iVars، فلا يزال من الممكن الوصول إليها/تغييرها عبر KVC، لأنه لا يوجد حتى الآن شيء مثل الطريقة الخاصة في Objective-C.

نصائح أخرى

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

لمعرفة مدى فائدة هذا يمكن أن يكون، والنظر في: CocoaDev

واحد من الرسوم التوضيحية المفضلة الفئات الهدف جيم في العمل هو NSString. ويعرف NSString في إطار المؤسسة، التي لا يوجد لديه فكرة وجهات النظر أو النوافذ. ومع ذلك، إذا كنت تستخدم NSString في تطبيق الكاكاو ستلاحظ أنه يستجيب للرسائل مثل – drawInRect:withAttributes:.

وAppKit يحدد فئة للNSString التي توفر أساليب الرسم إضافية. فئة تسمح أساليب جديدة لتضاف إلى فئة موجودة، لذلك نحن لا نزال مجرد التعامل مع NSStrings. إذا AppKit بدلا تنفيذها رسم من قبل إن شاء subclasses ترث سيكون لدينا للتعامل مع "AppKitStrings 'أو' NSSDrawableStrings" أو شيء من هذا القبيل.

والفئات تتيح لك إضافة تطبيق أو مجال أساليب محددة لالفئات الموجودة. ويمكن أن تكون قوية جدا ومريحة.

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

لسوء الحظ، هذا ليس هو الحال دائمًا أو حتى مرغوبًا فيه.في كثير من الأحيان يتم إعطاؤك مكتبة ثنائية/مجموعة كائنات ومجموعة من الرؤوس لتتعامل معها.

ثم هناك حاجة إلى وظيفة جديدة للفصل الدراسي حتى تتمكن من القيام بأمرين:

  1. أنشئ فئة جديدة بالكامل بدلاً من فئة الأسهم - وقم بتكرار جميع وظائفها وأعضائها ثم أعد كتابة كل التعليمات البرمجية لاستخدام الفئة الجديدة.

  2. قم بإنشاء فئة مجمعة جديدة تحتوي على فئة الأسهم كعضو (التركيب) وأعد كتابة قاعدة التعليمات البرمجية للاستفادة من الفئة الجديدة.

  3. تصحيحات ثنائية للمكتبة لتغيير الكود (حظا سعيدا)

  4. إجبار المترجم على رؤية فصلك الجديد على أنه الفصل القديم ونأمل ألا يعتمد على حجم معين أو مكان معين في الذاكرة ونقاط دخول محددة.

  5. تخصص الفئة الفرعية - إنشاء فئات فرعية لإضافة وظائف وتعديل رمز برنامج التشغيل لاستخدام الفئة الفرعية بدلاً من ذلك - من الناحية النظرية يجب أن تكون هناك مشكلات قليلة وإذا كنت بحاجة إلى إضافة أعضاء بيانات، فمن الضروري، ولكن مساحة الذاكرة ستكون مختلفة.لديك ميزة توفر كل من الكود الجديد والكود القديم في الفئة الفرعية واختيار الطريقة التي تريد استخدامها، أو طريقة الفئة الأساسية أو الطريقة التي تم تجاوزها.

  6. قم بتعديل فئة objc الضرورية باستخدام تعريف فئة يحتوي على طرق للقيام بما تريد و/أو تجاوز الطرق القديمة في فئات المخزون.

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

    مثال:

    لديك فئة Bing تقوم بالإخراج إلى محطة طرفية، ولكن ليس إلى منفذ تسلسلي، والآن هذا هو ما تحتاجه.(لسبب ما).لديك Bing.h وlibBing.so، ولكن ليس Bing.m في مجموعتك.

    تقوم فئة Bing بجميع أنواع الأشياء داخليًا، حتى أنك لا تعرف كل ما هي، لديك فقط واجهة برمجة التطبيقات العامة في الرأس.

    أنت ذكي، لذا قمت بإنشاء فئة (SerialOutput) لفئة Bing.

    [Bing_SerialOutput.m]
    @interface Bing (SerialOutput)   // a category
    - (void)ToSerial: (SerialPort*) port ;
    @end
    
    @implementation Bing (SerialOutput)
    - (void)ToSerial: (SerialPort*) port 
    {
    ... /// serial output code ///
    }
    @end
    

    يلتزم المترجم بإنشاء كائن يمكن ربطه بتطبيقك ويعرف وقت التشغيل الآن أن Bing يستجيب لـ @selector(ToSerial:) ويمكنك استخدامه كما لو تم إنشاء فئة Bing بهذه الطريقة.لا يمكنك إضافة أعضاء البيانات بطرق فقط ولم يكن المقصود من ذلك إنشاء أورام عملاقة من التعليمات البرمجية المرتبطة بالفئات الأساسية ولكن لها مزاياها مقارنة باللغات المكتوبة بدقة.

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

ويستخدم الميراث عند إنشاء التسلسل الهرمي فئة جديدة (جميع أجراس وصفارات) ويجلب يمكن القول الكثير من العمل عندما اختيرت طريقة إضافة وظائف إلى الفئات الموجودة.

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

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

أحد يعرف ما إذا كانت هناك حالات حيث هي ضرورية للغاية فئات؟

وA الفئة يشبه mixin: وحدة نمطية في روبي، أو إلى حد ما مثل واجهة في جافا. يمكنك التفكير في الأمر ب "أساليب المجردة". عند إضافة الفئة، وكنت إضافة طرق إلى الفئة. في مقالة ويكيبيديا لديها جيدة الاشياء .

وأفضل طريقة للنظر في هذا الاختلاف هو أن: 1. الوراثة: عندما تريد أن تتحول بالضبط في طريقك. على سبيل المثال: AsyncImageView لتنفيذ تحميل كسول. والتي تتم عن طريق وراثة UIView. 2. الفئة: نريد فقط لإضافة نكهة اضافية لذلك. مثال: نريد استبدال كافة المسافات من النص حيز النص في

   @interface UITextField(setText)
      - (NSString *)replaceEscape;
   @end

   @implementation UITextField(setText)
      - (NSString *)replaceEscape
      {
         self.text=[self.text stringByTrimmingCharactersInSet:
                           [NSCharacterSet whitespaceCharacterSet]];
         return self.text;
      }
   @end

و--- وسوف تضيف خاصية جديدة إلى حيز النص بالنسبة لك للنجاة من جميع المسافات. تماما مثل إضافة بعدا جديدا لأنه من دون تغيير تماما طريقها.

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