กลับไปหน้าบทความ

อ่าน 4 นาที

การโอเวอร์โหลดฟังก์ชัน

ในบางภาษา โปรแกรม การโอเวอร์โหลดฟังก์ชัน หรือ การโอเวอร์โหลดเมธอด คือความสามารถในการสร้าง ฟังก์ชัน หลายฟังก์ชัน ที่มีชื่อเดียวกันแต่มีการใช้งานที่แตกต่างกัน...

การโอเวอร์โหลดฟังก์ชัน

(Learn how and when to remove this message)

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

คำจำกัดความพื้นฐาน

ตัวอย่างเช่น`doTask()`และ`doTask(object o)` เป็นฟังก์ชันโอเวอร์โหลด ในการเรียกใช้ ฟังก์ชันหลังจะต้องส่งอ็อบเจ็กต์เป็นพารามิเตอร์ในขณะที่ฟังก์ชันแรกไม่ต้องการพารามิเตอร์ และถูกเรียกใช้โดยที่ช่องพารามิเตอร์ว่างเปล่า ข้อผิดพลาดที่พบบ่อยคือการกำหนดค่าเริ่มต้นให้กับอ็อบเจ็กต์ในฟังก์ชันที่สอง ซึ่งจะส่งผลให้เกิด ข้อผิดพลาด ในการเรียกใช้ที่ไม่ชัดเจนเนื่องจากคอมไพเลอร์จะไม่ทราบว่าควรใช้วิธีใดในสองวิธีนี้

อีกตัวอย่างหนึ่งคือ ฟังก์ชัน Print(object o)ที่ทำงานแตกต่างกันไปตามว่าเป็นการพิมพ์ข้อความหรือรูปภาพ ฟังก์ชันทั้งสองนี้สามารถโอเวอร์โหลดได้เป็นPrint(text_object T); Print(image_object P)หากเราเขียนฟังก์ชัน print ที่โอเวอร์โหลดสำหรับวัตถุทุกชิ้น โปรแกรมของเราจะ "พิมพ์" ได้โดยที่เราไม่ต้องกังวลเกี่ยวกับชนิดของวัตถุและการเรียกใช้ฟังก์ชันที่ถูกต้องอีกต่อไป การเรียกใช้จะเป็นPrint(something)เสมอ

ภาษาที่รองรับการโอเวอร์โหลด

ภาษาโปรแกรมที่รองรับการโอเวอร์โหลดฟังก์ชัน ได้แก่ แต่ไม่จำกัดเพียง:

ภาษาโปรแกรม ที่ ไม่รองรับการโอเวอร์โหลดฟังก์ชัน ได้แก่C , Python , RustและZig

กฎในการโอเวอร์โหลดฟังก์ชัน

  • มีการใช้ชื่อฟังก์ชันเดียวกันสำหรับคำจำกัดความฟังก์ชันมากกว่าหนึ่งรายการในโมดูล คลาส หรือเนมสเปซเดียวกัน
  • ฟังก์ชันจะต้องมีลายเซ็นประเภท ที่แตกต่างกัน กล่าวคือ แตกต่างกันในจำนวนหรือประเภทของพารามิเตอร์อย่างเป็นทางการ (เช่นใน C++) หรือเพิ่มเติมในประเภทการส่งคืน (เช่นใน Ada) [ 9 ]

การโอเวอร์โหลดฟังก์ชันมักเกี่ยวข้องกับภาษาการเขียนโปรแกรมแบบกำหนดประเภทคงที่ ซึ่งบังคับใช้ การตรวจสอบประเภทในการเรียกฟังก์ชันฟังก์ชันโอเวอร์โหลดคือชุดของฟังก์ชันที่แตกต่างกันซึ่งสามารถเรียกได้ด้วยชื่อเดียวกัน สำหรับการเรียกใดๆ คอมไพเลอร์จะพิจารณาว่าควรใช้ฟังก์ชันโอเวอร์โหลดใดและแก้ไขสิ่งนี้ในเวลาคอมไพล์นี่เป็นความจริงสำหรับภาษาการเขียนโปรแกรมเช่น Java [ 10 ]

การโอเวอร์โหลดฟังก์ชันแตกต่างจากรูปแบบโพลีมอร์ฟิซึม บางประเภท ที่การเลือกเกิดขึ้นในขณะรันไทม์ เช่น ผ่านฟังก์ชันเสมือนแทนที่จะเลือกแบบสแตติก

ตัวอย่าง: การโอเวอร์โหลดฟังก์ชันในภาษา C++

import std ;// ปริมาตรของลูกบาศก์int volume ( int s ) { return s * s * s ; }// ปริมาตรของทรงกระบอกdouble volume ( double r , int h ) { return std :: numbers :: pi * r * r * static_cast < double > ( h ); }// ปริมาตรของทรงสี่เหลี่ยมมุมฉาก (ปริซึมสี่เหลี่ยมผืนผ้า) long volume ( long l , int b , int h ) { return l * b * h ; }int main () { std :: println ( "{}" , volume ( 10 )); std :: println ( "{}" , volume ( 2.5 , 8 )); std :: println ( "{}" , volume ( 100l , 75 , 15 )); }

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

การโอเวอร์โหลดคอนสตรัคเตอร์

คอนสตรัคเตอร์ซึ่งใช้ในการสร้างอินสแตนซ์ของวัตถุ อาจถูกโอเวอร์โหลดได้ในภาษาการเขียนโปรแกรมเชิงวัตถุ บาง ภาษา เนื่องจากในหลายภาษา ชื่อของคอนสตรัคเตอร์ถูกกำหนดไว้ล่วงหน้าโดยชื่อของคลาส จึงดูเหมือนว่าจะมีคอนสตรัคเตอร์ได้เพียงตัวเดียวเท่านั้น เมื่อใดก็ตามที่ต้องการคอนสตรัคเตอร์หลายตัว จะต้องนำไปใช้เป็นฟังก์ชันโอเวอร์โหลด ในC++คอนสตรัคเตอร์เริ่มต้น จะไม่รับพารามิเตอร์ใดๆ โดยจะสร้างอินสแตนซ์ของ สมาชิกวัตถุด้วยค่าเริ่มต้นที่เหมาะสม "ซึ่งโดยปกติจะเป็นศูนย์สำหรับฟิลด์ตัวเลขและสตริงว่างสำหรับฟิลด์สตริง" [ 11 ]ตัวอย่างเช่น คอนสตรัคเตอร์เริ่มต้นสำหรับวัตถุบิลร้านอาหารที่เขียนด้วย C++ อาจตั้งค่าทิปเป็น 15%:

บิล() : ทิป{ 0.15 }, รวม{ 0.0 } {}

ข้อเสียของวิธีนี้คือต้องใช้สองขั้นตอนในการเปลี่ยนค่าของอ็อบเจ็กต์ Bill ที่สร้างขึ้น ต่อไปนี้แสดงวิธีการสร้างและเปลี่ยนค่าภายในโปรแกรมหลัก:

บิลค่าอาหาร; ทิป= 0.10 ; ยอดรวม= 4.00 ;

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

บิล( ทิปสองเท่า, ยอดรวมสองเท่า) : ทิป{ ทิป}, ยอดรวม{ ยอดรวม} {}

ตอนนี้ฟังก์ชันที่สร้างอ็อบเจ็กต์ Bill ใหม่สามารถส่งค่าสองค่าเข้าไปในคอนสตรัคเตอร์และกำหนดค่าให้กับสมาชิกข้อมูลได้ในขั้นตอนเดียว ตัวอย่างต่อไปนี้แสดงการสร้างและการกำหนดค่า:

บิลค่ากาแฟ( 0.10 , 4.00 );

วิธีนี้สามารถช่วยเพิ่มประสิทธิภาพของโปรแกรมและลดความยาวของโค้ดได้

อีกเหตุผลหนึ่งสำหรับการโอเวอร์โหลดคอนสตรัคเตอร์คือการบังคับให้สมาชิกข้อมูลต้องมีค่าบังคับ ในกรณีนี้ คอนสตรัคเตอร์เริ่มต้นจะถูกประกาศเป็น private หรือ protected (หรือควรลบออกไปเลยตั้งแต่C++11 ) เพื่อไม่ให้สามารถเข้าถึงได้จากภายนอก สำหรับบิลข้างต้น total อาจเป็นพารามิเตอร์เดียวของคอนสตรัคเตอร์ เนื่องจากบิลไม่มีค่าเริ่มต้นที่เหมาะสมสำหรับ total ในขณะที่ tip มีค่าเริ่มต้นเป็น 0.15

ภาวะแทรกซ้อน

มีสองประเด็นที่เกี่ยวข้องและทำให้การโอเวอร์โหลดฟังก์ชันซับซ้อนขึ้น ได้แก่การปกปิดชื่อ (เนื่องจากขอบเขต ) และการแปลงประเภทโดยปริยาย

หากมีการประกาศฟังก์ชันในขอบเขตหนึ่ง และจากนั้นมีการประกาศฟังก์ชันอื่นที่มีชื่อเดียวกันในขอบเขตภายใน จะมีพฤติกรรมการโอเวอร์โหลดที่เป็นไปได้ตามธรรมชาติสองแบบ: การประกาศภายในจะซ่อนการประกาศภายนอก (โดยไม่คำนึงถึงลายเซ็น) หรือทั้งการประกาศภายในและการประกาศภายนอกจะรวมอยู่ในการโอเวอร์โหลด โดยการประกาศภายในจะซ่อนการประกาศภายนอกก็ต่อเมื่อลายเซ็นตรงกันเท่านั้น ใน C++ จะใช้แบบแรก: "ใน C++ ไม่มีการโอเวอร์โหลดข้ามขอบเขต" [ 12 ]ดังนั้น เพื่อให้ได้ชุดโอเวอร์โหลดที่มีฟังก์ชันที่ประกาศในขอบเขตที่แตกต่างกัน จำเป็นต้องนำเข้าฟังก์ชันจากขอบเขตภายนอกไปยังขอบเขตภายในอย่างชัดเจนด้วยusingคำหลัก

การแปลงประเภทโดยปริยายทำให้การโอเวอร์โหลดฟังก์ชันซับซ้อนขึ้น เพราะหากประเภทของพารามิเตอร์ไม่ตรงกับลายเซ็นของฟังก์ชันโอเวอร์โหลดตัวใดตัวหนึ่งอย่างแม่นยำ แต่สามารถตรงกันได้หลังจากแปลงประเภทแล้ว การแก้ไขปัญหาจะขึ้นอยู่กับว่าเลือกใช้การแปลงประเภทแบบใด

สิ่งเหล่านี้สามารถรวมกันได้ในลักษณะที่สับสน: การจับคู่ที่ไม่ตรงกันเป๊ะที่ประกาศไว้ในขอบเขตภายในสามารถบดบังการจับคู่ที่ตรงกันเป๊ะที่ประกาศไว้ในขอบเขตภายนอกได้ ตัวอย่างเช่น[ 12 ]

ตัวอย่างเช่น หากต้องการมีคลาสที่สืบทอดมาซึ่งมีฟังก์ชันโอเวอร์โหลดที่รับค่าเป็นdoubleหรือintโดยใช้ฟังก์ชันที่รับค่าเป็นintจากคลาสพื้นฐาน ในภาษา C++ จะต้องเขียนดังนี้:

คลาสBase { public : void fn ( int i ); };class Derived : public Base { public : using Base :: fn ; void fn ( double d ); };

การไม่รวมusingผลลัพธ์ในintพารามิเตอร์ที่ส่งผ่านไปยังfnคลาสที่สืบทอดซึ่งถูกแปลงเป็นค่าทศนิยม และการจับคู่ฟังก์ชันในคลาสที่สืบทอด แทนที่จะเป็นในคลาสพื้นฐาน การรวมusingผลลัพธ์ในการโอเวอร์โหลดในคลาสที่สืบทอด และทำให้ตรงกับฟังก์ชันในคลาสพื้นฐาน

ข้อควรระวัง

หากเมธอดถูกออกแบบให้มีโอเวอร์โหลดมากเกินไป อาจทำให้ผู้พัฒนาแยกแยะได้ยากว่ากำลังเรียกใช้โอเวอร์โหลดใดโดยการอ่านโค้ดเพียงอย่างเดียว โดยเฉพาะอย่างยิ่งหากพารามิเตอร์บางตัวในโอเวอร์โหลดเป็นประเภทที่สืบทอดมาจากพารามิเตอร์อื่นๆ (เช่น "object") IDE สามารถทำการตรวจสอบโอเวอร์โหลดและแสดงผล (หรือนำทางไปยัง) โอเวอร์โหลดที่ถูกต้องได้

การโอเวอร์โหลดตามประเภทอาจขัดขวางการบำรุงรักษาโค้ดได้เช่นกัน โดยการอัปเดตโค้ดอาจทำให้คอมไพเลอร์เลือกโอเวอร์โหลดเมธอดโดยไม่ได้ตั้งใจ[ 13 ]

ดูเพิ่มเติม

การอ้างอิง

  1. ^ "Clojure - เรียนรู้ Clojure - ฟังก์ชัน" . clojure.org . สืบค้นเมื่อ2023-06-13 .
  2. ^ "เอกสารคริสตัล" . crystal-lang.org .
  3. ^ "Embarcadero Delphi" . embarcadero.com .
  4. ^ "ข้อกำหนดของภาษา Kotlin" . kotlinlang.org .
  5. ^ Bloch 2018 , หน้า 238-244, §บทที่ 8 ข้อ 52: กำจัดคำเตือนที่ไม่ได้ตรวจสอบ
  6. ^ "คู่มือการใช้งาน Nim" . nim-lang.org .
  7. ^ "37.6. การโอเวอร์โหลดฟังก์ชัน" . เอกสารประกอบ PostgreSQL . 2021-08-12 . สืบค้นเมื่อ2021-08-29 .
  8. ^ "คู่มือผู้ใช้และเอกสารอ้างอิง PL/SQL สำหรับฐานข้อมูล" . docs.oracle.com . สืบค้นเมื่อ2021-08-29 .
  9. ^วัตต์, เดวิด เอ.; ฟินด์เลย์, วิลเลียม (1 พฤษภาคม 2547). แนวคิดการออกแบบภาษาโปรแกรม . สำนักพิมพ์จอห์น ไวลีย์ แอนด์ ซันส์ อิงค์. หน้า  204–207 . ISBN 978-0-470-85320-7.
  10. ^ Bloch 2018 , หน้า 238-244, §บทที่ 8 ข้อ 52: ใช้การโอเวอร์โหลดอย่างรอบคอบ
  11. ^ Chan, Jamie (2017). เรียนรู้ C# ในหนึ่งวันและเรียนรู้ให้ดี (ฉบับปรับปรุง). หน้า 82. ISBN 978-1518800276.
  12. ^ a b Stroustrup, Bjarne . "ทำไมการโอเวอร์โหลดจึงใช้ไม่ได้กับคลาสที่สืบทอดมา?" .
  13. ^ Bracha, Gilad (3 กันยายน 2552). "ภาระเกินพิกัดของระบบ"ห้อง 101.
  • Meyer, Bertrand (ตุลาคม 2001). "Overloading vs Object Technology" (PDF)คอลัมน์ Eiffel วารสารการ เขียนโปรแกรมเชิงวัตถุ14 (4). 101 Communications LLC: 3– 7 สืบค้นเมื่อ27 สิงหาคม 2020
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Function_overloading&oldid=1344668986 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ การโอเวอร์โหลดฟังก์ชัน

ในบางภาษา โปรแกรม การโอเวอร์โหลดฟังก์ชัน หรือ การโอเวอร์โหลดเมธอด คือความสามารถในการสร้าง ฟังก์ชัน หลายฟังก์ชัน ที่มีชื่อเดียวกันแต่มีการใช้งานที่แตกต่างกัน...

คำจำกัดความพื้นฐาน

ตัวอย่างเช่น `doTask()` และ `doTask(object o)` เป็นฟังก์ชันโอเวอร์โหลด ในการเรียกใช้ ฟังก์ชัน หลังจะต้องส่งอ็อบเจ็กต์เป็น พารามิเตอร์ ในขณะที่ฟังก์ชันแรกไม่ต้องการพารามิเตอร์ และถูกเรียกใช้โดยที่ช่องพารามิเตอร์ว่างเปล่า...

ภาษาที่รองรับการโอเวอร์โหลด

ภาษาโปรแกรมที่รองรับการโอเวอร์โหลดฟังก์ชัน ได้แก่ แต่ไม่จำกัดเพียง:

กฎในการโอเวอร์โหลดฟังก์ชัน

การโอเวอร์โหลดฟังก์ชันมักเกี่ยวข้องกับภาษาการเขียนโปรแกรม แบบกำหนดประเภทคงที่ ซึ่งบังคับใช้ การตรวจสอบประเภท ใน การเรียกฟังก์ชัน ฟังก์ชันโอเวอร์โหลดคือชุดของฟังก์ชันที่แตกต่างกันซึ่งสามารถเรียกได้ด้วยชื่อเดียวกัน สำหรับการเรียกใดๆ...