Objective-C Programming Part III.

Polymorphisms

Polymorphisms สรุปง่ายๆว่าเป็นการอนุญาติให้ derived class ( child class ) สามารถใช้ function ของ parent ได้ สำหรับ polymorphisms นั้นเห็นเด่นชัดมากที่สุดก็คงจะเป็น Overriding / Overloading

  • Overriding
    เป็นการเขียน function ของ Child class ใช้เองโดยไม่ต้องใช้ function ของ Parent Class ถ้าจะยกตัวอย่างง่ายๆ ก็เป็นต้นว่า ถ้าเรามี class ชื่อว่า Car แล้ว Car นั้นมีฟังชั่นขื่อว่า drive สมมติว่าเราจะเขียน class ใหม่ขึ้นมาโดยสืบทอด (inherit) มาจาก Car โดยชื่อว่า Tank มีฟังชั่นชื่อว่า drive เหมือนกัน แต่ว่า class ทั้งสองนั้น Drive ทำงานไม่เหมือนกัน คือพูดง่ายๆว่า รถยนต์ก็ ขับ(drive)ได้ รถถังก็ ขับ(drive) ได้ แต่วิธีการที่จะขับไม่เหมือนกัน
  • Overloading
    เป็นการเขียน Function ชื่อเหมือนกัน ใน class เดียวกัน แต่รับ parameter คนละอย่างกัน เช่นว่า เรามี class ชื่อว่า Rectangle และมี function ในการคำนวนพื้นที่ เราอาจจะต้องการให้มันรับ parameter ได้ทั้ง int และ float ในลักษณะแบบนี้เราก็จะใช้ overloading เข้ามาให้เกิดประโยชน์

อาจจะงง เล็กน้อย สรุปสั้น Overriding ก็คือ child class ที่มีการเขียน function ที่ชื่อเหมือนกับ parent ขึ้นมาเองโดยไม่ต้องสืบทอดจาก parent และ Overloading คือ method ที่สามารถรับ parameter ได้หลายๆรูปแบบ

แต่มาดู code อาจจะเข้าใจง่ายกว่า

// Car.h
#import 
@interface Car:Object {
int m_speed;
}
- (void) drive;
- (void) drive:(int)speed;
@end

และในส่วน implement

// Car.m
#import 
@implementation Car;
- (void) drive
{
printf("Car drive n");
}
- (void) drive:(int)speed
{
m_speed = speed;
printf ("Car drive at speed %d n",m_speed); }
@end

จากตัวอย่างข้างบนเป็นการ แสดงให้เห็นถึง Overloading คือ จะเห็นว่า Car นั้นมี Function ชื่อเหมือนกัน นั่นคือ drive แต่รับ parameter มาไม่เหมือนกัน โดยที่ drive แรกนั้น ไม่ได้รับ parameter มาเลย ส่วนตัวที่สอง รับ int เข้ามาและ ก็ในส่วนการทำงานของแต่ละฟังชั่นก็ต่างกัน

เวลาเรียกใช้เราอาจจะเขียนได้ว่า

#import "car.h"
int main()
{
Car *honda = [[Car alloc] init];
[honda drive];
[honda drive:80];
return 0;
}

ส่วนผลลัพธ์ที่ออกมาก็จะเป็น

Car drive
Car drive at speed 80

ทีนี้เรามาดู Overriding กันบ้าง ก็อย่างที่บอกไปแล้วว่า เราสารมารถเขียน ให้ child class ทำงานต่างจาก parent โดยที่ ขื่อเหมือนกันได้มาดู กันเลยดีกว่า

// Tank.h
#import "car.h"
@interface Tank:Car {
}
@end

ก็จะเห็นว่าใน class tank นั้นไม่มีอะไรเลย คือ inherit มาจาก car อย่างเดียว แต่เราสารมารถเขียน implement ของตัวเองโดยอิงจาก parent ได้

#import "tank.h"
@implementation Tank
- (void) drive
{
printf ("Tank Driven");
}
@end

ก็เป็นอันเสร็จ คือเรา เขียน funtion drive ขึ้นมาใหม่ แทนที่ ตัวเก่าที่มีอยู่ใน Car

และก็มาลองเรียกใช้งานกันดู

#import "car.h"
#import "tank.h
int main()
{
Car *honda = [[Car alloc] init];
Tank *tank = [[Tank alloc] init];
[honda drive];
[tank drive];
[tank drive:20];
return 0;
}

ส่วนผลลัพธ์ที่ได้ก็จะได้ว่า

Car drive
Tank drive
Car drive at speed 20

จากผลลัพธ์ก็จะเห็นว่า Tank drive ที่ออกมา โปรแกรมจะไปเรียก function ใน class Tank

ส่วนบรรทัดสุดท้าย ตัวโปรแกรมจะไปเรียกใช้ parent ของ tank นั่นก็คือ Car เพราะเนื่องจากว่า tank นั้น Overriding เพียงแค่ฟังชั่น

- (void) drive;

แต่สำหรับ

- (void) drive:(int)speed;

ไม่ได้ทำการ overriding

มันจึงไปใช้งาน parent ของมันแทน

เพิ่มเติม http://gd.tuwien.ac.at/languages/c/c++oop-pmueller/
และ http://developer.apple.com/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/chapter_1_section_1.html

Technorati Tags: , , ,


7 responses so far, want to say something?

  1. Avatar

    alvanzoe says:

    ผมเข้าใจว่า [object action ] นี้เป็นหลัก syntax ของ Obj-C แล้ว
    [[Car alloc] init] แสดงว่า
    ส่วนนี้ [Car alloc] เป็น object และ [Car alloc] ต้อง return เป็น object มาใช่มั้ยครับ แล้ว Function init นี้ สืบทอดมาจาก NSObject ใช่มั้ยครับ

    iPhone SDK จะมาวันที่ 6 นี้แล้ว ผมยังไม่เข้าใจ syntax ของ Objective-C ซะเท่าไหร่เลย แล้ว พวก NSText,NSView ยังใช้ไม่ค่อยเป็นเลยครับ

    ขอบคุณสำหรับบทความดีๆ ครับ
    หาอ่านยากมากๆ Objective-C ภาษาไทย

  2. Avatar

    admin says:

    ครับก็เข้าใจถูกแล้วครับ [Car alloc] มันจะ เหมือนเป็นการบอกว่าสร้าง object ชนิด Car ขึ้นมานั่นเอง

    คือ Car *honda = [[Car alloc] init];
    ถ้าผมเขียนแบบยาวๆก็จะได้ว่า
    Car *honda; // Declare variable
    honda = [Car alloc]; // Allocate Memory for object
    [honda init]; // initial object

    ถ้าจะเทียบกับ ภาษา C/C++ ก็จะได้ว่า
    Car *honda;
    honda = new Car;
    honda->init();

    ส่วน init เป็น Function สืบทอดมาจาก NSObject ใช่แล้วครับ แต่ว่า อาจจะเห็นว่าผมเขียน Object แทนที่จะเป็น NSObject นี่ก็เพราะว่า เผื่อบางคน ไม่มี Mac แต่อยากลอง เขียน Objc ก็ต้องลง Mingw มันจะไม่มี NSObject แต่มี Object ซึ่งมันก็เหมือนกัน คือมันเป็น Foundation ของ Objc.

    ถ้าไม่เข้าใจก็อะไรก็ถามได้ครับ ยินดีตอบ (ถ้าตอบได้น่ะ)

  3. Avatar

    .... says:

    พี่เขียนผิดที่นึงอะ จาก Overloading พี่เขียนเป็น Overriding
    ลองหาดู

  4. Avatar

    admin says:

    แก้ไขแล้วครับ ขอบคุณมาก

  5. Avatar

    pondly says:

    พี่ค่ะ สงสัยตรง
    printf(“Car drive n”); <<< ตัว n นี้มันไว้ทำไรค่ะ
    printf ("Car drive at speed %d n",m_speed); <<< ตัว n นี้มันไว้ทำไรค่ะ

    รบกวนด้วยค่ะ

  6. Avatar

    adirak says:

    “\n” คือ slat n มันเป้นการบอกให้เว้นบรรทัดครับ แต่ใน html คงแสดงไม่ครบ

  7. Avatar

    kantae says:

    “ส่วน init เป็น Function สืบทอดมาจาก NSObject ใช่แล้วครับ”
    คือ ตอนที่ผมสรา้ง class ใหม่ใน xcode ให้เป็น child class ทีนี้ มันมี method
    - (id)init
    {
    self = [super init];
    if (self) {
    // Initialization code here.
    }

    return self;
    }
    ผมสามารถลบมันทิ้งได้มั้ยครับ เพราะว่ายังไงมันก็สืบทอดมาแล้ว ไม่ต้องเขียนก็ได้

Leave a Reply

You must be logged in to post a comment.