آبجکتیو-سی: تفاوت میان نسخه‌ها

محتوای حذف‌شده محتوای افزوده‌شده
2061.shy (بحث | مشارکت‌ها)
ایجاد متن اولیه
(بدون تفاوت)

نسخهٔ ‏۷ ژوئن ۲۰۰۹، ساعت ۱۶:۳۸

مقدمه

Objective-C یک زبان شی‌گرا است که با اضافه کردن مفاهیم ارسال پیام از زبان small talk به زبان C ایجاد شده است. در حال حاضر استفاده‌ی اصلی آن در محیط‌های Mac OS X و iPhone OS است. برنامه‌هایی از این زبان که از کتابخانه‌های خاص این محیط‌ها استفاده نکرده باشند در همه‌ی محیط‌هایی که کامپایلر gcc استفاده می‌شود قابل استفاده‌اند.

تاریخ‌چه

در سال‌های اولیه‌ی ۱۹۸۰ روش غالب در مهندسی نرم‌افزار روش برنامه‌سازی ساخت‌یافته بود. این روش بر مبنای اصل تقسیم مسئله به اجزای کوچک‌تر و حل تک‌تک آن‌ها بنا شده بود. با افزایش اندازه‌ی مسئله‌ها این روش به تدریج کارایی خود را از دست داد.

راه حل جدید پیشنهاد شده روش برنامه‌سازی شی‌گرا بود. زبان‌هایی مانند Smalltalk بر مبنای آن ساخته شدند.

Brad Cox و Tom Love زبان Objective-C را در سال‌های اولیه‌ی ۱۹۸۰ در کارخانه‌شان تولید کردند. Cox با الهام از زبان Smalltalk با تغییر در کامپایلر C توانست امکانات شی‌گرایی را به آن اضافه کند. او نام این زبان را OOPC مخفف Object Oriented Programming in C گذاشت. بعدها با کمک Love محصول جدیدی به نام Productivity Products International یا PPI را ساخت که یک کامپایلر Objective-C با کتابخانه‌ی کلاس‌های قدرت‌مند بود.

در سال 1988 شرکت NeXT مالکیت Objective-C را از StepStone خرید و کامپایلر و کتابخانه‌های خاص خودش را منتشر کرد. پروژه‌ی GNU نیز ورژن خودش به نام GNUStep را از کامپایلر این زبان منتشر کرد. بعد از خریده شدن NeXT توسط Apple این شرکت ابزارهایی برای کار با این زبان را منتشر کرد.

دستور زبان

زبان Objective-C یک لایه‌ی بسیار نازک روی زبان C است. هر برنامه‌ی C را می‌توان با کامپایلر Objective-C کامپایل کرد. اکثر دستورات از زبان C به ارث رسیده‌اند و تعدادی دستور برای ارسال پیغام به آن‌ها اضافه شده است.

پیام‌ها

زبان Objective-C روش‌هایی برای انتقال پیام به C اضافه کرد. در این زبان از مدل smalltalk برای فرستادن پیام استفاده می‌شود. در این روش یک پیام برای یک object فرستاده می‌شود و در صورتی که object گیرنده بخواهد آن را اجرا می‌کند. این روش برعکس روش C++ است که گیرنده باید حتماً یک متد را پیاده‌سازی کرده باشد تا شی‌ای بتواند آن را صدا بزند.

فرستادن یک پیام به یک شی در این زبان به شکل زیر است:

[obj method:parameter];

این دستور مانند عمل زیر در ++C است:

obj->method(parameter);

پیام‌های Objective-C نیازی ندارند که اجرا شوند.اگر به شیئی پیامی بدهیم و آن شی متد مربوطه را پیاده‌سازی کرده باشد. اجرا می‌شود و در غیر این صورت اجرا نمی‌شود. حتی می‌توان به nil نیز پیام فرستاد.

واسط‌ها و پیاده‌سازی‌ها

Objective-C نیاز دارد که واسط و پیاده‌سازی یک کلاس در بلوک‌های کد جداگانه قرار بگیرند. به طور قراردادی، واسط در یک فایل سرآیند با پسوند h. و پیاده‌سازی در یک فایل کد، معمولاً با پسوند m. قرار می‌گیرد.

واسط

واسط کلاس معمولاً در فایل سرآیند قرار می‌گیرد و معمولاً نام آن فایل سرآیند همان نام کلاس گذاشته می‌شود. نمونه‌ای از نحوه‌ی تعریف واسط

@interface classname : superclassname {
    // instance variables
}
+classMethod1;
+(return_type)classMethod2;
+(return_type)classMethod3:(param1_type)parameter_varName;
 
-(return_type)instanceMethod1:(param1_type)param1_varName :(param2_type)param2_varName;
-(return_type)instanceMethod2WithParameter:(param1_type)param1_varName andOtherParameter:(param2_type)param2_varName;
@end

+ نمایش‌گر توابع کلاس و – نمایش‌گر توابع مربوط به یک نمونه است. معادل کد بالا در ++C به شکل زیر است.

class classname : superclassname {
  // instance variables
  // Class (static) functions
  static void* classMethod1();
  static return_type classMethod2();
  static return_type classMethod3(param1_type parameter_varName);
 
  // Instance (member) functions
  return_type instanceMethod1(param1_type param1_varName, param2_type param2_varName);
  return_type instanceMethod2WithParameter(param1_type param1_varName, param2_type param2_varName=default);
};

یکی از موارد قابل توجه instanceMethod2WithParameter است. در Objective-C امکان استفاده از پارامتر‌دهی بانام‌ وجود دارد که در حال زیاد بودن تعداد پارامترها کد را تمیز نگاه می‌دارد. ولی در ++C چنین امکانی وجود ندارد.

مقادیر بازگشتی می‌توانند انواع C، یک اشاره‌گر به یک شی Objective-C و یا یک اشاره‌گر به انواع خاص مانند *NSArray یا *NSImage یا *NSString باشد. مقدار بازگشتی پیش‌فرض نوع عمومی Objective-C به نام id است.


پیاده‌سازی

واسط تنها روش دسترسی به کلاس را بیان می‌کند و نه خود متد‌ها را. کد اصلی در قسمت پیاده‌سازی نوشته می‌شود. این فایل‌های پیاده‌سازی معمولاً با m. خاتمه می‌یابند.

@implementation classname
+classMethod {
    // implementation
}
-instanceMethod {
    // implementation
}
@end

و هریک از این متدها به این شکل خواهند بود

-(int)method:(int)i {
    return [self square_root: i];
}

دستور زبان اجازه‌ی دادن مقدار با استفاده از اسم پارامترها را نیز می‌دهد.

مثلاً برای فراخوانی یک متد که این‌گونه تعریف شده است:

-(int)changeColorToRed:(float)red green:(float)green blue:(float)blue

می‌توان به این شکل عمل کرد

[myColor changeColorToRed:5.0 green:2.0 blue:6.0];

در پیاده‌سازی این زبان، هریک از این ارسال پیام‌ها تبدیل به یک function call می‌شود.

نمونه‌ گرفتن از یک کلاس

بعد از نوشتن کلاس Objective-C می‌توان از آن نمونه گرفت. برای این کار باید ابتدا برای شی حافظه بگیریم و سپس به آن مقدار اولیه بدهیم. این دو کار با دستوری مانند

MyObject * o = [[MyObject alloc] init];

قابل انجام‌اند. Alloc سبب می‌شود که به اندازه‌ی متغیرهای این کلاس حافظه گرفته شود و با init می‌توان به این متغیرها مقدار اولیه داد.

متد init معمولاً به صورت زیر نوشته می‌شود:

-(id) init {
    self = [super init];
    if (self) {
        ivar1 = value1;
        ivar2 = value2;
        .
        .
        .
    }
    return self;
}

پروتکل‌ها

پروتکل‌ها در زبان Objective-C برای معرفی مفهوم وراثت چندگانه به وجود آمدند. در این زبان وراثت چندگانه‌ی توصیفات وجود دارد و نه پیاده‌سازی‌ها. این همان مفهومی است که در ++C با وراثت از یک کلاس abstract و در Java به عنوان مفهوم interface وجود دارد.

در این زبان دو نوع پروتکل وجود دارد ad-hoc protocol که informal protocol نیز خوانده می‌شود و formal protocol. Informal protocol لیست متدهایی است که یک کلاس می‌تواند پیاده‌سازی کند. توی مستندات می‌آید زیرا هیچ معادلی در زبان ندارد. معمولاً شامل متدهای اختیاری نیز هست.

Formal protocol مشابه interface در Java است. یک لیست متدها است که یک کلاس می‌تواند بیان کند که آن‌ها را پیاده‌سازی می‌کند. این پروتکل‌ها نمی‌توانند هیچ‌گونه پیاده‌سازی داشته باشند.

تعریف یک formal protocol به این شکل است

@protocol Locking
- (void)lock;
- (void)unlock;
@end

و استفاده از آن در یک کلاس به صورت

@interface SomeClass : SomeSuperClass <Locking>
@end
است.

تعیین نوع پویا

Objective-C از تعیین نوع پویا پشتیبانی می‌کند. یک شی می‌تواند پیامی دریافت کند که در واسط آن مشخص نشده است که می‌تواند آن را دریافت کند. به این ترتیب انعطاف‌پذیری زبان افزایش می‌یابد.

در این‌جا یک شی می‌تواند یک پیام را دریافت کرده و با توجه به نوع آن، به یک شی دیگر ارسالش کند یا آن را به مدیر خطا بسپارد. همچنین می‌توان با اضافه کردن تعیین نوع استاتیک امکان چک کردن انواع ارسالی به یک شی در زمان کامپایل را به یک شی اضافه کرد.

ارسال کردن پیام

یک شی می‌تواند کارهای زیادی با یک پیام که برایش ارسال شده است انجام دهد. از جمله این که می‌تواند شی دریافت شده را به یک شی دیگر ارسال کند.

تفاوت‌های اساسی با ++C

  • ++C شامل کتابخانه‌ها و استاندارد‌هایی برای برنامه‌سازی شی‌گرا، برنامه‌سازی عمومی است. در حالی که Objective-C تنها یک لایه برای برنامه‌سازی شی‌گرا به C اضافه می‌کند.
  • Objective-C امکانات reflection برای برنامه‌نویس به وجود می‌آورد که در زمان اجرا آدرس بعضی توابع معلوم می‌گردد حال آن‌که در C++ امکانات reflection وجود ندارد. یعنی Objective-C از ++C امور بیشتری در زمان اجرا تعیین می‌شود که باعث انعطاف بیشتر زبان می‌شود ولی سرعت اجرای آن را کاهش می‌دهد.

تحلیل زبان

  • Objective-C برخلاف اکثر زبان‌های شی‌گرا که هم‌زمان با آن ساخته شدند از ماشین مجازی برای اجرای برنامه استفاده نمی‌کند.

این زبان می‌تواند روی یک کامپایلر زبان C پیاده‌سازی شود. به این ترتیب که اول به صورت پیش‌پردازشی کدهای خاص Objective-C تبدیل به کدهای C متناسب شوند.

  • این زبان برعکس ++C از operator overloading پشتیبانی نمی‌کند.

منابع

Cox, Brad J. (1991). Object Oriented Programming: An Evolutionary Approach. Addison Wesley. ISBN 0-201-54834-8.