سؤال

ما الفرق بين طريقة الفصل وطريقة مثيل؟

هل أساليب المثيلات تُعتبر أدوات الوصول (getters و petters) في حين أن أساليب الفصل هي إلى حد كبير كل شيء آخر؟

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

المحلول

كما قال معظم الإجابات الأخرى ، تستخدم أساليب المثيل مثيلًا للفصل ، في حين يمكن استخدام طريقة الفصل مع اسم الفصل فقط. في الهدف-C يتم تعريفها وبالتالي:

@interface MyClass : NSObject

+ (void)aClassMethod;
- (void)anInstanceMethod;

@end

يمكن بعد ذلك استخدامها مثل ذلك:

[MyClass aClassMethod];

MyClass *object = [[MyClass alloc] init];
[object anInstanceMethod];

بعض الأمثلة في العالم الحقيقي لطرق الطبقة هي أساليب الراحة في العديد من فصول الأساس مثل NSString+stringWithFormat: أو NSArray+arrayWithArray:. ستكون طريقة مثيل NSArray-count طريقة.

نصائح أخرى

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

enter image description here

أ صف دراسي هو مثل مخطط من المنزل: لديك مخطط واحد فقط و (عادة) لا يمكنك فعل ذلك كثيرًا مع المخطط وحده.

enter image description here

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

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

مثال جيد على طريقة الفصل هو طريقة من النوع المضاد ، والتي تُرجع العدد الإجمالي لحالات الفصل. تبدأ أساليب الفصل بـ +, ، في حين أن مثيلات تبدأ بـ -. فمثلا:

static int numberOfPeople = 0;

@interface MNPerson : NSObject {
     int age;  //instance variable
}

+ (int)population; //class method. Returns how many people have been made.
- (id)init; //instance. Constructs object, increments numberOfPeople by one.
- (int)age; //instance. returns the person age
@end

@implementation MNPerson
- (id)init{
    if (self = [super init]){
          numberOfPeople++;
          age = 0;
    }    
    return self;
}

+ (int)population{ 
     return numberOfPeople;
}

- (int)age{
     return age;
}

@end

Main.M:

MNPerson *micmoo = [[MNPerson alloc] init];
MNPerson *jon = [[MNPerson alloc] init];
NSLog(@"Age: %d",[micmoo age]);
NSLog(@"%Number Of people: %d",[MNPerson population]);

الإخراج: العمر: 0 عدد الأشخاص: 2

مثال آخر هو إذا كان لديك طريقة تريد أن يتمكن المستخدم من الاتصال به ، وأحيانًا يكون من الجيد أن تجعل طريقة الفصل هذه. على سبيل المثال ، إذا كان لديك فصل يسمى MathFunctions ، فيمكنك القيام بذلك:

+ (int)square:(int)num{ 
      return num * num;
}

إذن ، سيتصل المستخدم:

[MathFunctions square:34];

دون الاضطرار إلى إنشاء فئة!

يمكنك أيضًا استخدام وظائف الفئة لإرجاع الكائنات التي تم تصويرها التلقائي ، مثل NSArray's

+ (NSArray *)arrayWithObject:(id)object

يأخذ ذلك كائنًا ، ويضعه في صفيف ، ويعيد إصدارًا صدرًا من المصفوفة التي لا يجب أن تتم إدارتها للذاكرة ، وهي رائعة للمصفوفات المزاجية وما لا.

أتمنى أن تفهم الآن متى و/أو لماذا يجب أن تستخدم أساليب الفصل !!

تنطبق طريقة مثيل على مثيل للفئة (أي كائن) بينما تنطبق طريقة الفصل على الفئة نفسها.

في C# ، تم وضع علامة على طريقة الفئة. الأساليب والخصائص غير المميزة ثابتة هي طرق مثيل.

class Foo {
  public static void ClassMethod() { ... }
  public void InstanceMethod() { ... }
}

أعتقد أن أفضل طريقة لفهم ذلك هي النظر إلى alloc و init. كان هذا التفسير هو الذي سمح لي بفهم الاختلافات.

طريقة الفصل

يتم تطبيق طريقة الفصل على الفصل ككل. إذا قمت بفحص alloc الطريقة ، هذه طريقة فئة تشير إليها + قبل إعلان الطريقة. إنها طريقة فئة لأنه يتم تطبيقها على الفصل لإنشاء مثيل محدد لتلك الفئة.

طريقة مثيل

يمكنك استخدام طريقة مثيل لتعديل مثيل معين لفئة فريدة من نوعها في هذا المثال ، بدلاً من الفئة ككل. init على سبيل المثال (يشار إليه مع أ - قبل إعلان الطريقة) ، هي طريقة مثيل لأنك عادةً ما تقوم بتعديل خصائص تلك الفئة بعد إنشاءها alloc.

مثال

NSString *myString = [NSString alloc];

أنت تتصل بطريقة الفصل alloc من أجل إنشاء مثيل لتلك الفئة. لاحظ كيف يكون جهاز استقبال الرسالة فئة.

[myString initWithFormat:@"Hope this answer helps someone"];

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

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

الفرق بين طرق الفصل وطرق المثيل

طرق الفصل

  • تعمل على متغيرات الفصل (لا يمكن الوصول إلى متغيرات المثيل)
  • لا تتطلب تطبيق كائن لتطبيقه
  • في بعض الأحيان ، يمكن أن تكون رائحة رمز (بعض الأشخاص الجدد في استخدام OOP كقائد للقيام برمجة منظمة في eviroment oo oo)

طرق مثيل

  • تعمل على متغيرات الحالات ومتغيرات الفئة
  • يجب أن يكون لديك كائن مستسلم للعمل عليه

عادة ما تستخدم طرق الفصل لإنشاء مثيلات من تلك الفئة

فمثلا، [NSString stringWithFormat:@"SomeParameter"]; يعود NSString مثيل مع المعلمة التي يتم إرسالها إليها. وبالتالي ، لأنها طريقة فئة تُرجع كائنًا من نوعه ، وتسمى أيضًا طريقة الراحة.

لذلك إذا فهمت ذلك بشكل صحيح.

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

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

في معظم الاحتمالات (ما لم تكن تكتب مكتبة قابلة لإعادة الاستخدام ، يجب ألا تحتاج إلى ملف class عامل.

تعمل أساليب الحالات على مثيلات الفصول (أي "الكائنات"). ترتبط طرق الفصل بالفصول (معظم اللغات تستخدم الكلمة الرئيسية static لهؤلاء الرجال).

خذ على سبيل المثال لعبة يتم فيها إنتاج الكثير من السيارات .. كل منها ينتمي إلى الفئة CCAR. عندما يتم إنشاء مثيل للسيارة ، فإنها تقوم مكالمة

[CCar registerCar:self]

لذلك يمكن لفئة CCAR ، تقديم قائمة بكل CCAR. دعنا نقول أن المستخدم ينهي مستوى ، ويريد إزالة جميع السيارات ... يمكنك إما: 1- الذهاب من خلال قائمة كل ccar التي قمت بإنشائها يدويًا ، والقيام بها whicheverCar.remove();أو 2- أضف طريقة removeallcars إلى CCAR ، والتي سيفعل ذلك من أجلك عند الاتصال [CCAR removeallcars]. بمعنى آخر allCars[n].remove();

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

fontSize = thisMenu.getParent().fontHandler.getDefaultFontSize();

مع طريقة الفصل ، يمكنك الابتعاد [FontHandler getDefaultFontSize].

أما بالنسبة لوظيفة RemoveVowels الخاصة بك ، ستجد أن لغات مثل C# لديها في الواقع كل من الطرق مثل Tolower أو Toupper.

على سبيل المثال myString.removeVowels() و String.removeVowels(myString) (في OBJC سيكون ذلك [String removeVowels:myString]).

في هذه الحالة ، من المحتمل أن يستدعي المثيل طريقة الفصل ، لذلك يتوفر كلاهما. بمعنى آخر

public function toLower():String{
  return String.toLower();
}

public static function toLower( String inString):String{
 //do stuff to string..
 return newString;
}

في الأساس، myString.toLower() المكالمات [String toLower:ownValue]

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

طرق الفصل

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

طرق مثيل

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

في الهدف-C تبدأ جميع الطرق إما شخصية "-" أو "+". مثال:

@interface MyClass : NSObject
// instance method
- (void) instanceMethod;

+ (void) classMethod;
@end

تحدد الأحرف "+" و "-" ما إذا كانت الطريقة أ class method أو instance method على التوالى.

سيكون الفرق واضحًا إذا نسمي هذه الأساليب. هنا يتم الإعلان عن الأساليب في MyClass.

instance method تتطلب مثيلًا للفصل:

MyClass* myClass = [[MyClass alloc] init];
[myClass instanceMethod];

داخل MyClass طرق أخرى يمكن أن تستدعي طرق المثيل MyClass استخدام self:

-(void) someMethod
{
    [self instanceMethod];
}

ولكن، class methods يجب استدعاء الفصل نفسه:

[MyClass classMethod];

أو:

MyClass* myClass = [[MyClass alloc] init];
[myClass class] classMethod];

هذا لن ينجح:

// Error
[myClass classMethod];
// Error
[self classMethod];

طرق الفصل


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


طرق مثيل


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


يستحضر


لاستدعاء طريقة مثيل ، يمكنك إرسال الرسالة إلى مثيل للفصل.

لاستدعاء طريقة الفصل ، يمكنك إرسال الرسالة إلى الفصل مباشرة.


مصدر: iOS - Objective -C - أساليب الفصل وطرق المثيل

لا يمكن لتغيير طرق الفصل أو معرفة قيمة أي متغير مثيل. يجب أن تكون هذه هي المعايير لمعرفة ما إذا كانت طريقة مثيل يمكن أن تكون طريقة فئة.

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

يبدو أن المصطلح الشائع في مجتمع OBJ-C هو IVAR على سبيل المثال متغير ، لكنني لست رجل OBJ-C ، حتى الآن.

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

لم يعد هناك أي فرق بين طريقة المثيل وطريقة الفئة بعد أن وصل العد المرجعي التلقائي إلى الوجود في Objective-C.

فمثلا[NS StringWithformat:..] طريقة الفصل & [[NSString alloc] initwihtformat:..] طريقة مثيل ، كلاهما هو نفسه بعد قوس

ملحوظة: هذا فقط بتنسيق رمز الزائفة

طريقة الفصل

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

PlanetOfLiving: return @"Earth" // No matter how many times you run this method...nothing changes.

طريقة مثيل

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

initWithName: @"John" lastName: @"Doe"Age:12 @"cool"
initWithName: @"Donald" lastName: @"Drumpf"Age:5 attitude:@"He started"
initWithName: @"President" lastName: @"Obama"Age:54 attitude: @"Awesome"
//As you can see the value can change for each instance.

إذا كنت قادمًا من اللغات الأخرى ، فإن الأساليب الثابتة هي نفس طرق الفصل.
إذا كنت قادمًا من Swift ، فإن أساليب الكتابة هي نفس طرق الفصل.

إضافة إلى الإجابات أعلاه

طريقة الفصل سنعمل على الفصل ، سنستخدم هذا لغرض عام حيث مثل +stringWithFormat ، وحجم الفصل والأهم من ذلك لـ init إلخ

NSString *str = [NSString stringWithFormat:@"%.02f%%",someFloat]; 

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

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