PlusMagi's Blog By Pitt Phunsanit Backend,Database,Object-oriented Programming Java Polymorphism: ความต่างระหว่าง Compile-time (Overloading) และ Runtime Polymorphism (Overriding)

Java Polymorphism: ความต่างระหว่าง Compile-time (Overloading) และ Runtime Polymorphism (Overriding)

ในฐานะ Senior Architect การออกแบบระบบที่ยืดหยุ่น (Flexible) และสามารถขยายตัวได้ง่าย (Scalable) คือหัวใจสำคัญของงานวิศวกรรมซอฟต์แวร์ แนวคิดที่ช่วยให้เราบรรลุเป้าหมายนี้คือ Polymorphism หรือ ‘การมีหลายรูปแบบ’ ซึ่งเป็นหลักการสำคัญใน Object-Oriented Programming (OOP)

Polymorphism อนุญาตให้เราใช้ชื่อเมธอดหรือตัวแปรเดียว แต่สามารถทำงานที่แตกต่างกันไปตามบริบทของการเรียกใช้งาน ในภาษา Java (และแนวคิดที่นำมาประยุกต์ใช้ในระบบฐานข้อมูลเชิงวัตถุอย่าง PostgreSQL) เราแบ่งกลไกนี้ออกเป็นสองประเภทหลัก คือ Compile-time Polymorphism (Overloading) และ Runtime Polymorphism (Overriding) การเข้าใจความแตกต่างนี้คือกุญแจสำคัญในการออกแบบระบบที่แข็งแกร่งและดูแลรักษาง่าย

💡 1. Compile-time Polymorphism: Method Overloading

Overloading เกิดขึ้นเมื่อเรามีเมธอดหลายตัวในคลาสเดียวกันที่มีชื่อเหมือนกัน แต่รับพารามิเตอร์ (Signature) ที่แตกต่างกัน (เช่น จำนวนหรือชนิดของข้อมูล) คอมไพเลอร์จะสามารถตัดสินใจได้ตั้งแต่ขั้นตอนการคอมไพล์ว่าควรเรียกใช้เมธอดใดโดยดูจากประเภทและจำนวนของ Argument ที่ส่งเข้าไป

แนวคิดเชิงสถาปัตยกรรม: การออกแบบ API ที่มีหลายเวอร์ชันสำหรับงานที่คล้ายกัน แต่ถูกรวมไว้ภายใต้ชื่อเรียกหลักเดียว ทำให้ผู้ใช้งานเรียกใช้ฟังก์ชันได้ง่ายโดยไม่ต้องจำชื่อฟังก์ชันเฉพาะเจาะจง

ตัวอย่างการจำลอง Overloading ใน PostgreSQL (PL/pgSQL):

เราสามารถจำลอง Overloading โดยการสร้างฟังก์ชันที่มีชื่อเหมือนกันแต่รับ Argument ที่แตกต่างกัน:

SQL

-- ฟังก์ชันสำหรับประมวลผลสตริง (รับ 1 argument) 
CREATE OR REPLACE FUNCTION process_data(input_text TEXT) RETURNS TEXT AS $$ 
BEGIN 
    RETURN 'Processed Text: ' || input_text; 
END; 
$$ LANGUAGE plpgsql; 

-- ฟังก์ชันสำหรับประมวลผลตัวเลข (รับ 2 arguments) 
CREATE OR REPLACE FUNCTION process_data(a INTEGER, b INTEGER) RETURNS INTEGER AS $$ 
BEGIN 
    RETURN a + b; 
END; 
$$ LANGUAGE plpgsql; 

-- การเรียกใช้งาน: คอมไพเลอร์รู้ว่าจะเรียกใช้ฟังก์ชันไหน 
SELECT process_data('apple,banana,orange'); -- เรียกใช้เวอร์ชัน TEXT 
SELECT process_data(10, 20);                 -- เรียกใช้เวอร์ชัน INTEGER

💡 2. Runtime Polymorphism: Method Overriding

Overriding เกิดขึ้นเมื่อคลาสลูก (Subclass) มีการเขียนเมธอดที่มีชื่อและ Signature เดียวกันกับคลาสแม่ (Superclass) แต่ต้องการให้มีพฤติกรรมที่แตกต่างออกไป การตัดสินใจว่าจะเรียกใช้เมธอดใดจะเกิดขึ้นในขณะที่โปรแกรมกำลังทำงาน (Runtime) โดยขึ้นอยู่กับประเภทจริงของ Object ที่ถูกเรียกใช้งาน

แนวคิดเชิงสถาปัตยกรรม: ระบบต้องสามารถจัดการกับ Object ที่มีหลายรูปแบบ (เช่น Product, Service) โดยใช้ Interface หรือ Parent Class เดียวกัน แต่เมื่อเรียกใช้ฟังก์ชัน จะต้องรู้ว่า Object นั้นเป็นประเภทใดเพื่อเรียกใช้พฤติกรรมที่ถูกต้อง

การจำลอง Overriding ใน PostgreSQL (Conceptual):

ใน PostgreSQL เราจำลองแนวคิดนี้โดยการใช้ฟังก์ชันที่รับข้อมูลประเภท Record หรือ JSON ซึ่งให้ความยืดหยุ่นในการจัดการพฤติกรรมตามข้อมูลที่ป้อนเข้ามา:

SQL

-- สมมติว่าเรามีฟังก์ชันหลักที่ประมวลผล 'Item' 
CREATE OR REPLACE FUNCTION calculate_cost(item_type TEXT, price NUMERIC, quantity INTEGER) RETURNS NUMERIC AS $$ 
BEGIN 
    -- พฤติกรรมที่แตกต่างกันตามประเภท (Runtime Decision) 
    IF item_type = 'PRODUCT' THEN 
        RETURN price * quantity * 1.1; -- มีภาษี 
    ELSIF item_type = 'SERVICE' THEN 
        RETURN price * quantity;      -- ไม่มีภาษี 
    ELSE 
        RETURN 0; 
    END IF; 
END; 
$$ LANGUAGE plpgsql; 

-- การเรียกใช้งาน: ระบบตัดสินใจพฤติกรรม ณ Runtime 
SELECT calculate_cost('PRODUCT', 100.00, 2); -- ผลลัพธ์: 220.00 (มีภาษี) 
SELECT calculate_cost('SERVICE', 50.00, 3);  -- ผลลัพธ์: 150.00 (ไม่มีภาษี)

✅ สรุปความแตกต่างทางสถาปัตยกรรม

ความแตกต่างหลักคือ Overloading คือการตัดสินใจที่เกิดขึ้นตั้งแต่คอมไพล์ไทม์ (Compile-time) โดยดูจาก Signature ของเมธอด ส่วน Overriding คือการตัดสินใจที่เกิดขึ้นในขณะรันไทม์ (Runtime) โดยดูจากประเภทจริงของ Object หรือข้อมูลที่ถูกส่งเข้ามา

การเข้าใจหลักการเหล่านี้ช่วยให้เราออกแบบระบบฐานข้อมูลและแอปพลิเคชันที่สามารถรองรับการขยายตัวของฟังก์ชัน (Scalability) และมีความยืดหยุ่นสูง (Flexibility) โดยที่โค้ดหลักไม่จำเป็นต้องรู้รายละเอียดของทุกส่วนประกอบย่อย

Exit mobile version