Objective-C Programming Part III(2).

Dynamic Binding

คือไม่รู้ว่าจะอธิบายง่ายๆได้อย่างไรว่ามันคืออะไร แต่เอาเป็นว่า ขอยกตัวอย่าง Dynamic Binding ให้เห็นภาพได้ว่า สมมติว่า เรามี class ชื่อว่า Dog และ Cat โดนทั้งสอง class นี้เป็น child ของ Animal และมี function ชื่อว่า eat เหมือนกัน ดู code ตัวอย่างภาษา C ต่อไปนี้

void function_eat(Animal *a)
{
	a->eat();
}

ถ้าสมมติว่า เราเรียก funciton_eat โดยส่ง pointer ของ Cat และ dog มาให้ ในลักษณะแบบนี้

Cat *c = new Cat();
Dog *d = new Dog();
function_eat(c);
function_eat(d);

จะเห็นว่า เราสามารถส่ง ทั้ง Cat และ Dog ไปให้ function_eat ได้ เพราะว่าทั้ง Cat และ Dog นั้นเป็น Animal ทั้งคู่ ปัญหาก็คือว่าโปรแกรมจะรู้ได้ยังไงว่าควรจะไปเรียก eat ของ cat หรือว่าไปเรียก eat ของ dog ตรงนี้ไม่ต้องกังวลเพราะว่าโปรแกรมจะไปตรวจสอบเองว่า Animal ที่ได้รับมาเป็น dog หรือ cat กระบวนการที่โปรแกรมสามารถจำแนกได้ว่าเป็น class ใดนั้นเหละคือ Dynamic Binding

id Type

ในภาษา objective-c นั้นจะมีตัวแปรชนิดพิเศษที่ชื่อว่า id ตัวแปรชนิดนี้มันจะคล้ายๆลักษณะ pointer ในภาษา C แต่ id มันสามารถ เก็บค่าอะไรก็ได้ !!!

มาดูตัวอย่างอาจจะพอเห็นภาพมากกว่า

#import <stdio.h>
#import <Cocoa/Cocoa.h>
 
//---------- Human ------------
//------ Human Interface---------
@interface Human:Object
{
}
- (void) printHuman;
@end
//------ Human Implement ------
@implementation Human;
- (void) printHuman
{
	printf("Human \n");
}
@end
 
 
//---------- Animal ------------
//------ Animal Interface---------
@interface Animal:Object
{
}
- (void) printAnimal;
@end
//------ Animal Implement------
@implementation Animal;
- (void) printAnimal
{
	printf("Animal \n");
}
@end 
 
 
//------ MAIN ---------
int main()
{
	id both;
	Human *h = [[Human alloc] init];
	Animal *a = [[Animal alloc] init];
	both = h;
	[both printHuman];
	both = a;
	[both printAnimal];
	return 0;
}

คือจาก code ข้างบน ประกาศ class ไว้คือ Human กับ Animal และทั้งสอง class นี้ก็ไม่ได้เกี่ยวกันแต่อย่างได
มาดูที่ main โปรแกรมจะเห็นว่า ประกาศ ตัวแปรมา 3 ตัวก็คือ both , h , a ซึ่งทั้งสามตัวแปรนี้เป็นคนละชนิดกัน จุดที่อยากให้รู้ก็คือว่า เราประกาศ both เป็น id สามารถเก็บอะไรก็ได้ และ

  • เราก็ลองมาให้ both มีค่าเท่ากับ h หลังจากนั้นก็ลองเรียก printHuman
  • เสร็จแล้ว ก็ให้ both มีค่าเท่ากับ a แล้วก็เรียก printAnimal

จะเห็นว่ามันสามารถสลับเปลี่ยนไปเป็น Human หรือ Animal และเรียก function ของทั้งสองได้ ผลลัพธ์ที่ได้ก็จะเป็นแบบนี้

Human
Animal

และการใช้งานลักษณะแบบนี้ก็เป็น dynamic binding นั่นเอง ก็อาจจะเกิดคำถามที่ว่า ก็ในเมื่อมันเก็บได้ทุกอย่าง เราก็ประกาศให้มันเป็น id หมดเลยก็ได้ คำตอบก็คือได้ แต่ไม่ควรทำ ด้วยหลายๆเหตุผล ขอยกตัวอย่างง่ายๆว่า

id a;

กับ

Animal a;

สองอย่างนี้ อะไรเข้าใจง่ายกว่า ว่า a คืออะไร?
ระหว่างบอกว่า a เป็น animal กับ a เป็น id ?
จริงๆมันก็มีอีกหลายๆเหตุผลที่ว่า เราควรใช้ในสิ่งที่จำเป็นมากกว่า ขอยกตัวอย่าง อีกสักอัน

สมมติว่าจาก code ตัวอย่างแรก เรามาแก้ให้เป็นแบบนี้

boht = human;
[both  printAnimal];

จะเห็นว่า เราให้ both นั้นเป็น human แต่เรากลับไปเรียกใช้ printAnimal ซึ่งไม่มีใน Human แน่นอน … แต่เวลา Compile นั้นโปรแกรมจะไม่สามารถตรวจสอบได้ว่า มันไม่มี printAnimal โปรแกรมจะสามารถ Compile ได้ปกติโดยไม่เกิด error เพราะว่า dynamic binding นั้นจะเกิดขึ้นตอนโปรแกรมเริ่มทำงาน ดังนั้นถ้าเราเรียกใช้โปรแกรมดังกล่าว ก็จะเกิด error ทันที
และจะได้ผลลัพธ์ในลักษณะแบบนี้

Human
error: Animal (Instance)
Animal does not recognize  printHuman

ฉนั้นการใช้ก็ควรจะระวังกันสักนิด

Objective-C Programming Part III Source Files

Technorati Tags: , ,


Leave a Reply

You must be logged in to post a comment.