ภาษาอ็อบเจกทีฟ-ซี

จากวิกิพีเดีย สารานุกรมเสรี

(เปลี่ยนทางมาจาก ภาษาอ็อบเจกต์ทีฟซี)
Objective-C
กระบวนทัศน์ สมบัติการสะท้อน, การเขียนโปรแกรมเชิงวัตถุ
เริ่มเมื่อ พ.ศ. 2529
ออกแบบโดย Brad Cox and Tom Love
ผู้พัฒนา ปัจจุบัน บริษัทแอปเปิล, มูลนิธิซอฟต์แวร์เสรี
ระบบชนิดตัวแปร duck, static, weak
Major implementations gcc, llvm, Apple
ได้รับอิทธิพลมาจาก ภาษาสมอลทอล์ค, ภาษาซี
ส่งอิทธิพลต่อ TOM, Java, Objective-J

ภาษาอ็อบเจกทีฟ-ซี (อังกฤษ: Objective-C หรือ ObjC) เป็นภาษาโปรแกรมเชิงวัตถุและมีสมบัติการสะท้อน โดยแรกเริ่ม ภาษาอ็อบเจกทีฟ-ซี พัฒนาขึ้นจากภาษาซีโดยยังคงคุณลักษณะของภาษาซีไว้ครบทุกประการเพียงแต่เพิ่มระบบส่งข้อความ (messaging) แบบเดียวกับภาษาสมอลล์ทอล์กเข้าไปเท่านั้น (Objective-C runtime) ปัจจุบันภาษาอ็อบเจกทีฟ-ซีมีคุณสมบัติอื่นๆเพิ่มเติมจากการพัฒนาภาษาอ็อบเจกทีฟ-ซี 2.0 โดยบริษัทแอปเปิล

ปัจจุบันภาษาอ็อบเจกทีฟ-ซีถูกใช้มากใน Cocoa (API) ใน Mac OS X, GNUstep (API) และ Cocotron (API) เป็นต้น ซึ่งระบบเหล่านี้ได้รับการพัฒนาขึ้นโดยมีพื้นฐานจากมาตรฐาน OpenStep (API) ใน Nextstep (Operating system) โดยมีภาษาภาษาอ็อบเจกทีฟ-ซีเป็นภาษาหลัก ปัจจุบัน Mac OS Xใช้ Cocoa เป็นเฟรมเวิร์กสำหรับสร้างโปรแกรมประยุกต์ โดย ไลบรารีและ/หรือ API เหล่านี้เป็นเพียงส่วนเพิ่มขยาย (Software extension) เท่านั้น โปรแกรมที่ใช้ภาษาอ็อบเจกทีฟ-ซีทั่วไปที่ไม่ได้ใช้ส่วนเพิ่มขยายเหล่านี้ก็ยังสามารถคอมไพล์ได้ เช่นอาจใช้แต่ gcc ซึ่งรองรับภาษาอ็อบเจกทีฟ-ซี

เนื้อหา

[แก้] ประวัติ

ในช่วงต้นของปี 1980s วิศกรรมซอฟต์แวร์นิยมออกแบบโปรแกรมแบบโครงสร้าง เรานิยามการออกแบบโปรแกรมแบบโครงสร้างขึ้นเพื่อแยกย่อยโปรแกรมขนาดใหญ่ลงเป็นส่วนเล็กๆ เพื่อให้ง่ายต่อการจัดการเมื่อโปรแกรมมีขนาดใหญ่ขึ้น อย่างไรก็ดี โปรแกรมแบบโครงสร้างก็มีประโยชน์น้อยลงเมื่อขนาดของปัญหาใหญ่ขึ้น เพราะต้องเขียน procedure จำนวนมากเพื่อรองรับปัญหาที่ใหญ่ขึ้น และทำให้รหัสคำสั่งมีความซับซ้อนและยุ่งเหยิง

ทางเลือกหนึ่งสำหรับแก้ปัญหาดังกล่าวคือการเขียนโปรแกรมเชิงวัตถุ ที่จริงแล้วภาษาสมอลล์ทอล์กก็ได้แก้ไขข้อบกพร่องในกระบวนการวิศวกรรมซอฟต์แวร์เหล่านี้ แต่ในอดีตสมอลทอล์คก็มีปัญหาในแง่ของความเร็วและการใช้หน่วยความจำมากเนื่องจากคอมพิวเตอร์ในสมัยก่อนมีข้อจำกัดมากกว่าในปัจจุบัน

ในต้นยุค 80 Brad Cox และ Tom Love ได้ให้พัฒนาภาษาอ็อบเจ็กทีฟ-ซีขึ้นที่บริษัท Stepstone ของพวกเขา โดยพวกเขาได้เรียนรู้ภาษาสมอลล์ทอล์กจาก Programming Technology Center ของบริษัท ITT Corporation ในปีค.ศ. 1981 Cox ให้ความสนใจกับปัญหาเรื่องการนำรหัสมาใช้ซ้ำ (reusability) ในกระบวนการวิศวกรรมซอฟต์แวร์ เขาคิดว่าภาษาสมอลล์ทอล์กไม่เหมาะจะใช้พัฒนา development environment สำหรับนักพัฒนาซอฟต์แวร์ระบบที่ ITT Cox เริ่มแก้ไขคอมไพเลอร์ภาษาซี โดยเพิ่มความสามารถด้านการจัดการเชิงวัตถุของภาษาสมอลล์ทอล์กเข้าไป โดยเขาเรียกมันว่า "OOPC" หมายถึง Object-Oriented Programming in C ในขณะนั้น Love ซึ่งทำงานให้กับ Schlumberger Research ในปี 1982 ก็ได้มีโอกาสใช้งาน Smalltalk-80 ซอฟต์แวร์ซึ่งส่งอิทธิพลต่อการพัฒนาภาษาอ็อบเจกทีฟ-ซีในเวลาต่อมา

และเพื่อแสดงประสิทธิภาพ Cox ได้แสดงให้เห็นว่าการปรับปรุงเครื่องมือที่มีอยู่แล้วเพียงเล็กน้อยก็สามารถทำ software component ให้ปรับเปลี่ยนได้ง่ายๆ โดยการทำ object ให้ยืดหยุ่นและสนับสนุนด้วยชุดไลบรารีซึ่งประกอบด้วยรหัสและรีซอร์ส ที่รวมกันอยู่ในรูปแบบที่สามารถนำไปใช้ข้าม platform ได้

Cox และ Love ได้ก่อตั้ง Productivity Products International (PPI) เพื่อขายคอมไพเลอร์ภาษาอ็อบเจกทีฟ-ซีและคลาสไลบรารีในเวลาต่อมา

ในปีค.ศ. 1986 Cox ได้ตีพิมพ์หนังสือที่อธิบายถึงภาษาอ็อบเจกทีฟ-ซีชื่อ Object-Oriented Programming, An Evolutionary Approach ซึ่งแม้ว่า Cox จะได้พยายามชี้ให้ว่าปัญหาหลักคือการนำรหัสมาใช้ซ้ำ (reusability) มากกว่าจะเป็นการแก้ปัญหาด้วยภาษา แต่กระนั้น Objective-C ก็ยังถูกนำไปเรียบเทียบแบบฟีเจอร์ต่อฟีเจอร์กับภาษาอื่นๆอยู่ดี

[แก้] แพร่หลายเพราะ NeXT

ในปีค.ศ. 1988 บริษัท NeXT ซึ่งตั้งขึ้นโดย Steve Jobs ได้ลิขสิทธิ์จาก StepStone (เจ้าของเครื่องหมายการค้าภาษาอ็อบเจกทีฟ-ซีในขณะนั้น) โดยได้พัฒนาคอมไพเลอร์ภาษาอ็อบเจกทีฟ-ซีและชุดไลบรารี ของตัวเองโดยนำมาใช้พัฒนาระบบติดต่อผู้ใช้และระบบพัฒนาซอฟต์แวร์ชื่อ NEXTSTEP ถึงแม้ว่าเครื่อง NeXT จะขายไม่ดี แต่เครื่องมือพัฒนาของมันกลับได้รับความนิยมพอสมควร และในที่สุด NeXT ก็เลิกขายฮาร์ดแวร์ และหันมาขายซอฟต์แวร์แทน ภายใต้ชื่อ NeXTstep และ OpenStep

โครงการกนู ได้พัฒนาระบบพัฒนาซอฟต์แวร์หนึ่งตามมาตรฐาน OpenStep ในรูปแบบซอฟต์แวร์เสรี โดย Dennis Glatting ได้พัฒนา gnu-objc runtime ตัวหนึ่งขึ้นในปี 1992 โดย Richard Stallman ได้เขียนอีกตัวขึ้นแทนในเวลาไล่เลี่ยกัน ส่วน GNU Objective-C runtime ตัวที่ถูกใช้งานตั้งแต่ 1993 พัฒนาโดย Kresten Krab Thorup เมื่อเขาเป็นนักเรียนมหาวิทยาลัยในเดนมาร์ค

หลังจากที่ซื้อกิจการของ NeXT ในปี 1996 Apple ได้ใช้ OpenStep ในระบบปฏิบัติการของตนเองหรือ Mac OS X โดยได้รวมเอาภาษาอ็อบเจกทีฟ-ซีและระบบพัฒนาซอฟต์แวร์จาก NeXT ชื่อ Project Builder ซึ่งถูกแทนที่โดย Xcode ในเวลาต่อมา รวมถึงระบบออกแบบระบบการติดต่อผู้ใช้แบบ object ชื่อ Interface Builder และ Apple เรียกไลบรารีซึ่งพัฒนาต่อจาก OpenStep ว่า Cocoa

[แก้] Syntax

ภาษาอ็อบเจกทีฟ-ซี [1]เป็นชั้นบางๆ บน C และเป็น สตริกต์ superset ของ C ดังนั้นคอมไพเลอร์ภาษาอ็อบเจกทีฟ-ซีจึงสามารถคอมไพล์โปรแกรมภาษา C ใดๆ ก็ได้ ภาษาอ็อบเจกทีฟ-ซี ได้รับรูปแบบการเขียนมาจากภาษาซีและภาษาสมอลล์ทอล์ก โดยรูปแบบส่วนใหญ่ (preprocessing, expressions, การประกาศฟังค์ชัน และการเรียกฟังค์ชัน) มาจากภาษาซี ขณะที่ส่วนที่เป็นการจัดการเชิงวัตถุมาจากสมอลทอล์ค

[แก้] Messages

ภาษาอ็อบเจกทีฟ-ซีได้เพิ่มเติมรูปแบบการเขียนโปรแกรม เพื่อรองรับการออกแบบโปรแกรมเชิงวัตถุ โดยจะใช้การส่ง message ไปยัง object ต่างๆเช่นเดียวกับสมอลทอล์ค ซึ่งแตกต่างจากภาษาในตระกูล Simula (เช่น C++) ข้อแตกต่างมีมีความสำคัญ เพราะภาษาอ็อบเจกทีฟ-ซีจะไม่เรียก method แต่จะส่ง message

ในภาษาอ็อบเจกทีฟ-ซี ถ้ามี object หนึ่งชื่อ obj โดย class มี method ชื่อ doSomething หมายความว่า obj respond หรือตอบสนองต่อ message doSomething และถ้าเราต้องการจะส่ง message doSomething ไปยัง obj เราจะเขียนคำสั่งดังนี้

[obj doSomething];

ขณะที่ถ้าเป็น C++ เราจะเขียนว่า

obj.doSomething () ;


[แก้] Forwarding

ในภาษาอ็อบเจกทีฟ-ซีจะยอมให้มีการส่ง message ไปยัง object ใดๆ แม้ว่าจะไม่มีการเตรียม method เอาไว้รองรับ (คือไม่ respond) ต่างจากภาษาอื่นๆ เช่น C++ หรือ Java ที่การเรียกใช้ method ต้องมีการระบุไว้ล่วงหน้า หาก object ได้รับ message ที่ไม่รู้จัก object จะผ่านต่อ message ที่ได้รับไปยัง method เหล่านี้

- (retval_t) forward:(SEL) sel :(arglist_t) args; // with GCC
- (id) forward:(SEL) sel :(marg_list) args; // with NeXT/Apple systems

method เหล่านี้อาจแตกต่างกันไปตามชนิดของ runtime และมักนิยมผ่านต่อไปยัง method อื่นๆในระดับของ framework เช่น forwardInvocation: [2] ใน OpenStep

[แก้] อินเตอร์เฟซ และ อิมพลีเมนเทชัน

ในภาษาอ็อบเจกทีฟ-ซี ส่วนอินเตอร์เฟซ (@interface) และอิมพลีเมนเทชัน (@implementation) จะถูกแยกออกจากกัน ในทางปฏิบัติ เรามักเก็บส่วนอินเตอร์เฟซไว้ในแฟ้ม .h และส่วนอิมพลีเมนเทชันใน .m

[แก้] @interface

เรามักนิยามส่วนอินเตอร์เฟซของคลาสในแฟ้ม .h โดยทั่วไปเรามักตั้งชื่อแฟ้มนี้ให้ตรงหรือสอดคล้องกับชื่อของคลาส เช่นถ้าคลาสเราชื่อ Thing เราก็มักจะประกาศอินเตอร์เฟซของคลาส Thing ในแฟ้ม Thing.h

รูปแบบของการประกาศอินเตอร์เฟซมีลักษณะดังนี้:

@interface classname : superclass name
{
    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

method แบบ instance จะถูกนำหน้าด้วยเครื่องหมายลบ "-" ส่วน method แบบ class จะถูกนำหน้าโดยเครื่องหมายบวก "+" ตรงนี้จะแตกต่างจาก UML diagrams ซึ่งใช้ในแสดงว่า method เป็นแบบ private หรือ public

ค่าที่ถูก return จาก method มีลักษณะเช่นเดียวกับในภาษาซี เช่น void, int, ฯลฯ โดยจะมีการประกาศ type ชื่อ id ไว้แทน instance อ็อบเจกอะไรก็ได้

เราประกาศพารามิเตอร์ของ method ด้วยเครื่องหมายทวิภาคหรือโคลอน ":" ตามด้วย type ของพารามิเตอร์ในวงเล็บ แล้วตามด้วยชื่อของพารามิเตอร์ เรามักใส่ชื่อที่มีความสอดคล้องกับพารามิเตอร์หน้าเครื่องหมายทวิภาค เพื่อบอกว่าพารามิเตอร์แต่ละตัวมีบทบาทอย่างไร

-(void) setRange: (int) start : (int) end;
-(void) importDocumentWithName: (NSString *) name withSpecifiedPreferences: (Preferences *) prefs beforePage: (int) insertPage;

[แก้] @implementation

ส่วนอินเตอร์เฟซจะประกาศแต่ต้นแบบของ method เท่านั้น โดยไม่รวมถึงการกำหนดว่า method นั้นจะต้องทำอะไรบ้าง การกำหนดว่า method นั้นจะต้องทำอะไรจะทำในส่วนอิมพลีเมนเทชัน ตามปรกติ ส่วนอิมพลีเมนเทชันจะอยู่ในไฟล์นามสกุล .m ตัวอย่างเช่น Thing.m ที่มีการกำหนดส่วนอิมพลีเมนเทชันไว้ดังนี้

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

method มีหน้าตาแตกต่างจากฟังค์ชันในภาษา C เช่นถ้าในภาษาซีเป็นอย่างนี้

int do_something (int i)
{
    return square_root (i) ;
}

โดยมี int do_something (int) เป็นต้นแบบ

เมื่อมาประกาศเป็น method ในภาษาอ็อบเจ็กทีฟ-ซี จะมีหน้าตาอย่างนี้

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

ถ้าให้ถูกธรรมเนียมเราจะกำหนดชื่อ method ข้างต้นใหม่ โดยเราจะตั้งชื่อ method ให้สอดคล้องกับ argument ตัวแรกดังนี้

- (int) doSomethingWithInt: (int) i
{
    return [self squareRootOfInt:i];
}

แม้ว่าอาจจะดูยุ่งยากแต่ก็ช่วยให้เราจำ argument ได้ง่ายขึ้น ตัวอย่างเช่น

- (int) changeColorWithRed: (int) r  green: (int) g  blue: (int) b

โดยเราจะเรียก method แบบนี้:

[myColor changeColorWithRed:5 green:2 blue:6];

คอมไพเลอร์ภาษาอ็อพเจ็กทีฟ-ซีแต่ละตัวก็จะกำหนดชื่อ method เป็นการภายในแตกต่างกันไป เช่นถ้า method -changeColorWithRed:green:blue: เป็น method แบบ instance ของ class Color คอมไพเลอร์ก็อาจจำ method นี้ในชื่อ _i_Color_changeColorWithRed_green_blue เป็นต้น โดยตัว i จะบอกว่าจุดนี้คืออิมพลีเมนเทชัน method แบบ instance และตามด้วยชื่อคลาสและชื่อ method และมีการเปลี่ยนเครื่องหมาย : เป็น _ ดังนี้แล้ว เมื่อพารามิเตอร์เป็นส่วนหนึ่งของชื่อ method ลำดับของพารามิเตอร์ในภาษาอ็อบเจ็กทีฟ-ซีจึงสลับที่กันไม่ได้

อย่างไรก็ตาม เราแทบไม่ได้ใช้ชื่อภายในของฟังชั่นโดยตรง โดยทั่วไป การส่ง message จะถูกเปลี่ยนให้อยู่ในรูปแบบของการเรียกฟังค์ชั่นที่กำหนดไว้ในไลบราลีส่วน run-time และปรกติเวลาเราส่ง message เราก็จะไม่คำนึงถึง class ที่แท้จริงของส่วน receiver (myColor) อยู่แล้ว นั่นคือการจัดการหา method จะเป็นหน้าที่ของ run-time

[แก้] Objective-C 2.0

เป็นส่วนเพิ่มเติม syntax จากภาษา Objective-C โดยบริษัท Apple เป็นผู้พัฒนาเพิ่ม[3]เช่น

  • Garbage collection (computer science) (ทั้งนี้ ใน Objective-C runtime ของ GNU สามารถใช้งาน Boehm-Demers-Weiser conservative garbage collector ได้ก่อนหน้า Objective-C 2.0 แล้ว[4])
  • Properties (@property) ช่วยจัดการการประกาศ instance variable
  • Fast enumeration[5] การเพิ่มประสิทธิภาพในส่วน runtime [6]
for (int i=0; i<[thePeople count]; i++) {
    Person *p = [thePeople objectAtIndex:i];
    NSLog (@"%@ is %i years old.", [p getName], [p getAge]) ;
}
 
for (Person *p in thePeople)
    NSLog (@"%@ is %i years old.", [p getName], [p getAge]) ;

[แก้] Objective-C++

เป็นส่วนเพิ่มภาษาที่ช่วยให้รวม code Objective-C และ C++ เข้าด้วยกันง่ายขึ้น

[แก้] คอมไพเลอร์

  • gcc
  • llvm [7]
  • POC[8] มีจุดเด่นเช่นการรองรับ block แบบ smalltalk

[แก้] อ้างอิง

  1. ^ Cox, Brad J. (1991). Object Oriented Programming: An Evolutionary Approach. Addison Wesley. ISBN 0-201-54834-8. 
  2. ^ http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/doc/uid/20000050-forwardInvocation_
  3. ^ http://lists.apple.com/archives/Objc-language/2006/Aug/msg00039.html
  4. ^ http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_3.html
  5. ^ Apple, Inc. (2007). Fast Enumeration. สืบค้นวันที่ 2008-06-09
  6. ^ http://lists.apple.com/archives/Objc-language/2006/Aug/msg00018.html
  7. ^ http://clang.llvm.org/
  8. ^ http://users.pandora.be/stes/compiler.html
เครื่องมือส่วนตัว