[Java] ความแตกต่างระหว่าง Overloading กับ Overriding
Overload & Override ความสับสนของคำศัพท์ เป็นอะไรที่พบกันได้บ่อยๆ แม้แต่คนที่มีประสบการณ์แล้วหรือมือใหม่ ก็มักเข้าใจผิดกันว่า ความจริงแล้วมันคืออะไรกันแน่ อาจเป็นเพราะเป็นเรื่องที่หนักไปทางทฤษฎีซะมากกว่า
จากโค้ดตัวอย่างนี้ ผมสร้าง 2 คลาสที่สืบทอดกัน ซึ่งแต่ละคลาสมีการประกาศเมธอด getName() เหมือนกันแบบเป๊ะๆ ตามที่ได้กล่าวไว้ข้างต้น โดย
สังเกตว่าในคลาส Man ที่สืบทอดมาจาก Human นั้น ผมได้วาง
จริงๆ แล้ว การทำงานของมันอาจไม่เหมือนกันเลยก็ได้ แต่ว่าตามหลักคือเราต้องตั้งชื่อต่างๆให้สัมพันธ์กับการทำงาน แปลว่า การที่เราจะ Overload นั้น ก็ต้องมีการทำงานที่คล้ายๆกัน เพียงแต่ความจำเป็นบางอย่างที่อาจทำให้เราต้อง Overload เช่น การทำงานมันเหมือนกันแต่ว่าต่างกันที่ parameter ก็ไม่รู้จะเอาชื่ออื่นว่าอะไรดี ตามตัวอย่างที่จะให้ดูต่อไปนี้ครับ
คลาส Human มีการ getName 2 แบบ คือ แบบที่ไม่มี parameter ก็จะ return คำว่า "I'm Human" ไป แต่กรณีที่ส่ง parameter 2 ตัวมาด้วย เช่น
จะเห็นว่า การ Override จะทำให้เมธอดเดิม (ใน superclass) เปลี่ยนไป แต่ Overload นั้นคล้ายกับการที่เราสร้างเมธอดขึ้นมาใหม่ เพียงแต่มีชื่อเดียวกัน เพราะฉะนั้นทุกเมธอดที่ทำ overload ไม่ได้ถูกทับไปเหมือน override และแน่นอนว่า ทั้ง 2 อย่างนี้ สามารถใช้ร่วมกันก็ได้ เพราะว่ามันไม่เหมือนกัน จะสืบทอดแล้ว Override มาแล้วก็ Overload อีกทีก็ไม่มีปัญหา อยู่ที่เราว่าจะออกแบบมันอย่างไร
Overload ช่วยเราได้ตอนเวลาตั้งชื่อเมธอด แต่บางครั้งเวลาเจอโค้ดเยอะๆ ก็เล่นเอางงเหมือนกันว่า ตกลงแล้วไอ้เมธอดที่ว่านี้มันอันไหนกันแน่ ต้องไล่โค้ดให้ละเอียดลงไปอีกว่า parameter มีกี่ตัว, data type เป็นอะไร ค่อนข้างทำให้สับสนพอสมควร บางครั้งผมเลือกที่จะตั้งเป็นชื่ออื่นไปแทน เช่น จาก
สุดท้ายขอจบด้วย quote ที่ได้เจอมา (จากที่ไหนซักที่) ครับ
http://javarevisited.blogspot.com/2011/08/what-is-polymorphism-in-java-example.html
Overriding Method
บังคับเลยครับว่า มันจะต้องมาพร้อมกับการสืบทอด (Inheritance) เพราะว่า Override นั้นคือการ implement เมธอดนั้นๆใหม่ ทั้ง modifier, return type, ชื่อเมธอด, parameter(s) จะเหมือนเดิม มีแค่เนื้อข้างในที่เป็นการทำงานเท่านั้นที่เปลี่ยนไป ขอยกตัวอย่างด้วย Java แบบง่ายๆ นะครับจากโค้ดตัวอย่างนี้ ผมสร้าง 2 คลาสที่สืบทอดกัน ซึ่งแต่ละคลาสมีการประกาศเมธอด getName() เหมือนกันแบบเป๊ะๆ ตามที่ได้กล่าวไว้ข้างต้น โดย
getName()
จะ return เป็นคำว่าอะไร ก็อยู่ที่ว่าเราเรียกใช้เมธอดนี้ จาก object ของคลาสไหนนั่นเองสังเกตว่าในคลาส Man ที่สืบทอดมาจาก Human นั้น ผมได้วาง
@Override
ซึ่งเรียกว่าการทำ Annotation ในที่นี้เป็นการระบุว่าเมธอดที่เราเขียนนี้ Override มาจาก superclass ถ้าเราเขียนเมธอดไม่เหมือนกับที่มีอยู่ใน superclass ก็จะมี error เกิดขึ้นOverloading Method
มักจะถูกเรียกผิดๆ ว่า Override หรือบางคน อาจเข้าใจว่ามันคือสิ่งเดียวกัน แต่ความจริงแล้ว มันไม่ใช่นะครับ สำหรับคำนี้ จะเกี่ยวข้องกับการสืบทอดหรือไม่ก็ได้ ลักษณะของมันก็คือ เป็นเมธอดที่ชื่อเหมือนกัน แต่อย่างอื่น(return type หรือ parameter) ตั้งแต่หนึ่งอย่างขึ้นไปไม่เหมือนกัน เท่านี้ก็ถือว่ามันคือการทำ Overload ครับจริงๆ แล้ว การทำงานของมันอาจไม่เหมือนกันเลยก็ได้ แต่ว่าตามหลักคือเราต้องตั้งชื่อต่างๆให้สัมพันธ์กับการทำงาน แปลว่า การที่เราจะ Overload นั้น ก็ต้องมีการทำงานที่คล้ายๆกัน เพียงแต่ความจำเป็นบางอย่างที่อาจทำให้เราต้อง Overload เช่น การทำงานมันเหมือนกันแต่ว่าต่างกันที่ parameter ก็ไม่รู้จะเอาชื่ออื่นว่าอะไรดี ตามตัวอย่างที่จะให้ดูต่อไปนี้ครับ
คลาส Human มีการ getName 2 แบบ คือ แบบที่ไม่มี parameter ก็จะ return คำว่า "I'm Human" ไป แต่กรณีที่ส่ง parameter 2 ตัวมาด้วย เช่น
getName("Java","Developer");
ก็จะไปเข้าเมธอดด้านล่างแทนจะเห็นว่า การ Override จะทำให้เมธอดเดิม (ใน superclass) เปลี่ยนไป แต่ Overload นั้นคล้ายกับการที่เราสร้างเมธอดขึ้นมาใหม่ เพียงแต่มีชื่อเดียวกัน เพราะฉะนั้นทุกเมธอดที่ทำ overload ไม่ได้ถูกทับไปเหมือน override และแน่นอนว่า ทั้ง 2 อย่างนี้ สามารถใช้ร่วมกันก็ได้ เพราะว่ามันไม่เหมือนกัน จะสืบทอดแล้ว Override มาแล้วก็ Overload อีกทีก็ไม่มีปัญหา อยู่ที่เราว่าจะออกแบบมันอย่างไร
ประสบการณ์ส่วนตั๊ว ส่วนตัว
Override เป็นสิ่งจำเป็นที่ต้องใช้อย่างหลีกเลี่ยงไม่ได้ โดยเฉพาะกับภาษาที่เป็น OOP อย่าง Java เพราะถ้าเราจะเขียนพวก interface, implements ยังไง ๆ ก็ต้อง OverrideOverload ช่วยเราได้ตอนเวลาตั้งชื่อเมธอด แต่บางครั้งเวลาเจอโค้ดเยอะๆ ก็เล่นเอางงเหมือนกันว่า ตกลงแล้วไอ้เมธอดที่ว่านี้มันอันไหนกันแน่ ต้องไล่โค้ดให้ละเอียดลงไปอีกว่า parameter มีกี่ตัว, data type เป็นอะไร ค่อนข้างทำให้สับสนพอสมควร บางครั้งผมเลือกที่จะตั้งเป็นชื่ออื่นไปแทน เช่น จาก
getName()
ถ้ามี parameter เพิ่มก็ตั้งเป็น getNameByNickname("...","...")
เป็นต้นสุดท้ายขอจบด้วย quote ที่ได้เจอมา (จากที่ไหนซักที่) ครับ
Overriding is the concept of runtime polymorphism while,
Overloading is the concept of compile time polymorphism...