ภาษาอ็อบเจกทีฟ-ซี
ภาษาอ็อบเจกทีฟ-ซี (อังกฤษ: Objective-C หรือ ObjC) เป็นภาษาโปรแกรมเชิงวัตถุและมีสมบัติการสะท้อน โดยแรกเริ่ม ภาษาอ็อบเจกทีฟ-ซี พัฒนาขึ้นจากภาษาซีโดยยังคงคุณลักษณะของภาษาซีไว้ครบทุกประการเพียงแต่เพิ่มระบบส่งข้อความ (messaging) แบบเดียวกับภาษาสมอลล์ทอล์กเข้าไปเท่านั้น (Objective-C runtime) ปัจจุบันภาษาอ็อบเจกทีฟ-ซีมีคุณสมบัติอื่นๆเพิ่มเติมจากการพัฒนาภาษาอ็อบเจกทีฟ-ซี 2.0 โดยบริษัทแอปเปิล
กระบวนทัศน์ | สมบัติการสะท้อน, การเขียนโปรแกรมเชิงวัตถุ |
---|---|
ผู้ออกแบบ | Brad Cox และ Tom Love |
ผู้พัฒนา | ปัจจุบัน บริษัทแอปเปิล, มูลนิธิซอฟต์แวร์เสรี, llvm |
เริ่มเมื่อ | พ.ศ. 2529 |
รุ่นเสถียร | |
ระบบชนิดตัวแปร | duck, static, weak |
เว็บไซต์ | developer |
ตัวแปลภาษาหลัก | |
gcc, Clang | |
ได้รับอิทธิพลจาก | |
ภาษาสมอลทอล์ค, ภาษาซี | |
ส่งอิทธิพลต่อ | |
TOM, Java, Objective-J, Swift |
ปัจจุบันภาษาอ็อบเจกทีฟ-ซีถูกใช้มากใน 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
วากยสัมพันธ์
แก้ภาษาอ็อบเจกทีฟ-ซี [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
แก้เป็นส่วนเพิ่มเติมวากยสัมพันธ์จากภาษา 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
- clang (llvm) [7]
- POC[8] มีจุดเด่นเช่นการรองรับ block แบบ smalltalk
อ้างอิง
แก้- ↑ Cox, Brad J. (1991). Object Oriented Programming: An Evolutionary Approach. Addison Wesley. ISBN 0-201-54834-8.
- ↑ http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/doc/uid/20000050-forwardInvocation_
- ↑ "สำเนาที่เก็บถาวร". คลังข้อมูลเก่าเก็บจากแหล่งเดิมเมื่อ 2009-06-18. สืบค้นเมื่อ 2009-01-01.
- ↑ http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_3.html
- ↑ Apple, Inc. (2007). "Fast Enumeration". สืบค้นเมื่อ 2008-06-09.
{{cite web}}
: ไม่รู้จักพารามิเตอร์|=
ถูกละเว้น (help) - ↑ "สำเนาที่เก็บถาวร". คลังข้อมูลเก่าเก็บจากแหล่งเดิมเมื่อ 2010-11-24. สืบค้นเมื่อ 2009-01-01.
- ↑ http://clang.llvm.org/
- ↑ "สำเนาที่เก็บถาวร". คลังข้อมูลเก่าเก็บจากแหล่งเดิมเมื่อ 2008-08-02. สืบค้นเมื่อ 2008-12-30.