อะไรคือความแตกต่างระหว่างการโหลดเมธอดและการแทนที่ใน Java?


10

อะไรคือความแตกต่างระหว่างการโหลดเมธอดและการแทนที่ใน Java?

ลายเซ็นของเมธอด, ตัวระบุการเข้าถึง, ชนิดส่งคืนมีความแตกต่างกันหรือไม่?


3
ใน PHP มากไปมีความหมายที่แตกต่างกันอย่างสิ้นเชิง
lortabac

คำตอบ:


41

ในการโอเวอร์โหลดเมธอดด้วยเมธอดใหม่เมธอดใหม่ควรมีลายเซ็นที่แตกต่างกัน คือสองวิธีที่โอเวอร์โหลดมีชื่อเดียวกัน แต่มีพารามิเตอร์ต่างกัน นี่คือตัวอย่างของวิธีการโอเวอร์โหลดสองวิธี:

boolean isOdd(int number) { ... };
boolean isOdd(float number) { ... };

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

เมื่อเมธอดถูกแทนที่แล้วเมธอดใหม่จะมีลายเซ็นเหมือนกันและแทนที่เมธอด overridden ในบางกรณี นี่คือตัวอย่างของวิธีการแทนที่:

public class A 
{
     public void someMethod() { ... }
}

public class B extends A
{
     public void someMethod() { ... }
}

ตัวเลือกถูกสร้างขึ้นตามชนิดของวัตถุ ตัวอย่างเช่น,

A someA = new B();
someA.someMethod();

จะเรียกของsomeMethod Bคุณสามารถ (และควร) เพิ่มคำอธิบายประกอบ @Override:

public class B extends A
{
     @Override
     public void someMethod() { ... }
}

ตอนนี้ถ้าคุณเปลี่ยนพารามิเตอร์ใน B โดยไม่ตั้งใจคอมไพเลอร์จะแจ้งให้คุณทราบว่าคุณไม่ได้เอาชนะ someMethod () แต่ให้โหลดมากเกินไป


@ scarfridge ขอบคุณสำหรับการแก้ไข ยังไม่ได้เขียนโปรแกรมกับ Java สำหรับอายุและลืมมาก)))
superM

1
ขอขอบคุณที่พูดถึงคำอธิบายประกอบ @Override และความจริงที่ว่าการส่งคืนชนิดที่แตกต่างกันเท่านั้นไม่ได้ทำให้วิธีการแทนที่ แต่แทนที่จะโหลดเกิน
Daniel Dinnyes

13

มากไปวิธีการมีชื่อเดียวกัน แต่พารามิเตอร์ที่แตกต่าง

การแทนที่การใช้งานที่กำหนดในคลาสฐานจะถูกแทนที่ด้วยในคลาสย่อย


1
โปรดอย่าแก้ไข / ขยายสิ่งนี้ ความกะทัดรัดเป็นจุด
NimChimpsky

7

แนวคิดที่คุณถามเกี่ยวกับการครอบคลุมในบทเรียน Java

คำอธิบายสำหรับการเอาชนะมีดังนี้:

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

ความสามารถของคลาสย่อยในการแทนที่เมธอดช่วยให้คลาสสืบทอดจากซูเปอร์คลาสที่มีพฤติกรรม "ใกล้พอ" แล้วปรับเปลี่ยนพฤติกรรมตามต้องการ เมธอดการแทนที่มีชื่อหมายเลขและชนิดของพารามิเตอร์เดียวกันและชนิดส่งคืนเป็นเมธอดที่แทนที่ เมธอดการแทนที่ยังสามารถส่งคืนชนิดย่อยของชนิดที่ส่งคืนโดยเมธอด overridden นี้เรียกว่าชนิดกลับ covariant

เมื่อแทนที่เมธอดคุณอาจต้องการใช้@Overrideหมายเหตุประกอบที่สั่งให้คอมไพเลอร์ที่คุณต้องการแทนที่เมธอดในซูเปอร์คลาส หากด้วยเหตุผลบางอย่างคอมไพเลอร์ตรวจพบว่าวิธีการไม่มีอยู่ในหนึ่งในซูเปอร์คลาสมันจะสร้างข้อผิดพลาด สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ@Overrideดูคำอธิบายประกอบ ...

การโอเวอร์โหลดมีการอธิบายในบทช่วยสอนดังนี้:

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

สมมติว่าคุณมีคลาสที่สามารถใช้การเขียนตัวอักษรเพื่อวาดข้อมูลประเภทต่างๆ (สตริงจำนวนเต็มและอื่น ๆ ) และที่มีวิธีการวาดรูปแบบข้อมูลแต่ละชนิด มันเป็นความยุ่งยากในการใช้ชื่อใหม่สำหรับแต่ละวิธีตัวอย่างเช่นdrawString, drawInteger, drawFloatและอื่น ๆ ในภาษาการเขียนโปรแกรม Java คุณสามารถใช้ชื่อเดียวกันสำหรับวิธีการวาดทั้งหมด แต่ส่งผ่านรายการอาร์กิวเมนต์ที่แตกต่างกันไปยังแต่ละวิธี ดังนั้นคลาสการวาดข้อมูลอาจประกาศชื่อเมธอดสี่วิธีdrawซึ่งแต่ละรายการมีรายการพารามิเตอร์ที่แตกต่างกัน ...

เมธอดที่โอเวอร์โหลดมีความแตกต่างจากจำนวนและชนิดของอาร์กิวเมนต์ที่ส่งผ่านไปยังเมธอด ...

คุณไม่สามารถประกาศมากกว่าหนึ่งวิธีที่มีชื่อเดียวกันและหมายเลขและชนิดของอาร์กิวเมนต์ที่เหมือนกันได้เนื่องจากคอมไพเลอร์ไม่สามารถแยกพวกมันออกได้

คอมไพเลอร์ไม่พิจารณาประเภทการส่งคืนเมื่อแยกแยะวิธีการดังนั้นคุณจึงไม่สามารถประกาศสองวิธีด้วยลายเซ็นเดียวกันแม้ว่าพวกเขาจะมีประเภทผลตอบแทนแตกต่างกันก็ตาม


หมายเหตุ:ควรใช้วิธีการโอเวอร์โหลดมากเกินไปเนื่องจากจะทำให้โค้ดอ่านน้อยลงมาก


คำอธิบายข้างต้นสำหรับคุณสมบัติที่กล่าวถึงมากเกินไปที่กล่าวถึงในบทเรียนหัวข้อ"การเชื่อมต่อและการรับมรดก" :

ในคลาสย่อยคุณสามารถโหลดเมธอดที่สืบทอดจากซูเปอร์คลาสได้ เมธอดที่โอเวอร์โหลดดังกล่าวไม่ได้ซ่อนหรือแทนที่เมธอดซูเปอร์คลาส - เป็นเมธอดใหม่ที่ไม่ซ้ำกับคลาสย่อย


2

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

โดยทั่วไปแล้วการแทนที่เมธอดจะถูกกำหนดเป็น "การจัดให้มีการใช้งานที่แตกต่างกันในคลาสที่ได้รับมาของเมธอดที่มีลายเซ็นเฉพาะที่กำหนดไว้ในคลาสพื้นฐาน" มีเหตุผลมากมายที่จะลบล้างเมธอด จริง ๆ แล้วทั้งหมดของพวกเขามีเหมือนกันความจริงที่ว่าชั้นเรียนที่ได้รับมีความรู้เพิ่มเติมเกี่ยวกับสิ่งที่ต้องทำซึ่งชั้นฐานไม่สามารถทราบได้ มีสองรสชาติของการเอาชนะในภาษา OO ส่วนใหญ่; การแทนที่สามารถแทนที่เมธอดคลาสพื้นฐานหรือสามารถขยายได้วิธีการเรียนระดับพื้นฐาน ความแตกต่างคือโดยปกติแล้วคลาสที่ได้รับซึ่งขยายการใช้งานคลาสพื้นฐานจะเรียกเมธอดทับรุ่นคลาสพื้นฐานในบางช่วงระหว่างการดำเนินการของเมธอดแทนที่ สิ่งนี้ยอมให้คลาสที่แทนที่ "พื้นที่ใช้ซ้ำ" ของการดำเนินการซึ่งมีอยู่ในคลาสพื้นฐาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.