เราควร @Override การใช้วิธีการอินเตอร์เฟซ?


432

ควรทำหมายเหตุประกอบวิธีที่ใช้วิธีการเชื่อมต่อกับ@Override?

Javadoc ของOverrideคำอธิบายประกอบพูดว่า:

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

ฉันไม่คิดว่าอินเทอร์เฟซเป็นซูเปอร์คลาสในทางเทคนิค หรือมันคืออะไร?

Question Elaboration


5
ว้าวคำถามนี้อาจจะสั้นลง แต่มันเป็นคำถามที่ฉันต้องการ ขอบคุณ
Dan Rosenstark

1
ฉันไม่พบการแทนที่สำหรับบทความ @Override (Oracle ย้ายบล็อก Sun เก่าเมื่อเร็ว ๆ นี้) คุณรู้วิธีค้นหามันอย่างไร?
Bill the Lizard

4
เราควรมีคำอธิบายประกอบ @Implement โดยตอนนี้ (2015) นั่นจะทำให้สิ่งต่าง ๆ ชัดเจน!
อเล็กซ์

3
โดยตอนนี้ (2015) เราควรใช้ @Override กับ java 8 หรือไม่
Lorenzo Sciuto

คำตอบ:


305

คุณควรใช้ @Override ทุกครั้งที่ทำได้ มันป้องกันข้อผิดพลาดง่าย ๆ จากการทำ ตัวอย่าง:

class C {
    @Override
    public boolean equals(SomeClass obj){
        // code ...
    }
}

public boolean equals(Object obj)นี้ไม่ได้รวบรวมเพราะมันไม่ได้ถูกแทนที่

สิ่งเดียวกันนี้จะใช้สำหรับวิธีการที่ใช้อินเทอร์เฟซ ( 1.6 ขึ้นไปเท่านั้น ) หรือแทนที่วิธีของ Super class


150
โปรดทราบว่าคุณไม่สามารถเพิ่มคำอธิบายประกอบ @Override ให้กับวิธีการใช้งานอินเทอร์เฟซใน Java 5 - มันสร้างข้อผิดพลาด อนุญาตให้ใช้ใน Java 6
Bill Michell

17
อืมไม่เลย ในความเป็นจริง Eclipse แทรกอัตโนมัติ @Override เมื่อกรอกวิธีการที่ใช้อินเตอร์เฟซ
jjnguy

14
-1 จนกว่าคำตอบจะกล่าวถึงเกี่ยวกับพฤติกรรมที่แตกต่างจาก Java 1.5 ถึง 1.6 เกี่ยวกับการใช้วิธีการอินเทอร์เฟซ เพียงเพราะฉันเห็นว่ามันเป็นเรื่องที่สร้างความสับสนให้กับผู้คนและมันก็เป็นการกล่าวขวัญที่ดี
Grundlefleck

2
หาก eclipse บ่นให้อัพเกรด ur jdk เป็น> 1.5 และเปลี่ยนระดับความสอดคล้องของคอมไพเลอร์เป็น 1.6 หรือ 1.7 ในการทำเช่นนั้นคลิกขวาที่ ur project-> properties-> Java compiler และเลือกอันที่สูงกว่า 1.5
โรส

1
ทุกคนสามารถนึกถึงตัวอย่างที่แสดงความเป็นจริงของคำตอบ (การใช้อินเทอร์เฟซมากกว่าการแทนที่เมธอดพื้นฐาน) ข้อดีอย่างหนึ่งสำหรับฉันคือมันช่วยกำหนดความคาดหวังของผู้อ่านว่าจะใช้วิธีการเฉพาะและวิธีการใด
Joe Lee-Moyet

103

ฉันเชื่อว่าพฤติกรรม javac มีการเปลี่ยนแปลง - ด้วย 1.5 มันห้ามการเพิ่มความคิดเห็นด้วย 1.6 ไม่ได้ คำอธิบายประกอบจะมีการตรวจสอบเวลาคอมไพล์พิเศษดังนั้นหากคุณใช้ 1.6 ฉันจะลองดู


1
การตรวจสอบพิเศษคืออะไร?
Michael Carman

17
@Michael คุณสามารถสังเกตเห็นว่าอินเทอร์เฟซใด ๆ ได้ถูกลบ
Sanghyun Lee

68

คุณควรอธิบายวิธีการด้วยเสมอ@Overrideหากมี

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

equals(Object)เทียบกับequals(YourObject)ตัวอย่างเป็นกรณีมาตรฐานในการจุด แต่อาร์กิวเมนต์เดียวกันสามารถสร้างขึ้นมาเพื่อการใช้งานอินเตอร์เฟซ

ฉันคิดว่าเหตุผลที่ไม่จำเป็นในการใส่คำอธิบายประกอบวิธีการใช้อินเทอร์เฟซคือ JDK 5 ตั้งค่าสถานะนี้ว่าเป็นข้อผิดพลาดในการคอมไพล์ หาก JDK 6 บังคับให้ใช้คำอธิบายประกอบนี้จะทำให้ความเข้ากันได้ย้อนหลัง

ฉันไม่ใช่ผู้ใช้ Eclipse แต่ใน IDE อื่น ๆ (IntelliJ) @Overrideคำอธิบายประกอบจะถูกเพิ่มเมื่อใช้วิธีการอินเตอร์เฟสเท่านั้นหากโปรเจ็กต์ถูกตั้งค่าเป็นโครงการ JDK 6+ ฉันคิดว่า Eclipse นั้นคล้ายกัน

อย่างไรก็ตามฉันต้องการที่จะเห็นคำอธิบายประกอบที่แตกต่างกันสำหรับการใช้งานนี้อาจเป็น@Implementsคำอธิบายประกอบ



11

JDK 5.0 ไม่อนุญาตให้คุณใช้@Overrideคำอธิบายประกอบหากคุณใช้วิธีการที่ประกาศในอินเตอร์เฟส (ข้อผิดพลาดในการรวบรวม) แต่ JDK 6.0 อนุญาต ดังนั้นอาจเป็นไปได้ว่าคุณสามารถกำหนดค่าโครงการตามความต้องการของคุณ


4

หากคลาสคอนกรีตไม่ได้แทนที่เมธอด abstract การใช้@Overrideสำหรับการนำไปใช้เป็นเรื่องเปิดเนื่องจากคอมไพเลอร์จะเตือนคุณถึงวิธีการใด ๆ ในกรณีเหล่านี้อาร์กิวเมนต์สามารถทำว่ามัน detracts จากการอ่าน - มันเป็นสิ่งที่มากขึ้นในการอ่านรหัสของคุณและในระดับน้อยก็จะเรียกว่าไม่@Override@Implement


3

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


3

มันไม่ใช่ปัญหาของ JDK ใน Eclipse Helios อนุญาตให้ใช้คำอธิบายประกอบ @Override สำหรับวิธีการอินเตอร์เฟสที่นำไปใช้งานไม่ว่าจะเป็น JDK 5 หรือ 6 สำหรับ Eclipse Galileo ไม่อนุญาตให้ใช้คำอธิบายประกอบ @Override ไม่ว่าจะเป็น JDK 5 หรือ 6 ก็ตาม


2

สำหรับฉันบ่อยครั้งนี่เป็นเหตุผลเดียวที่บางรหัสต้องการ Java 6 ในการคอมไพล์ ไม่แน่ใจว่ามันคุ้มค่าหรือไม่


2

โดยการอ่าน javadoc ใน java8 คุณสามารถค้นหาสิ่งต่อไปนี้ได้ที่การประกาศของ Override อินเตอร์เฟส:

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

  • วิธีการจะแทนที่หรือใช้วิธีการประกาศใน supertype
  • วิธีนี้มีลายเซ็นต์ที่เทียบเท่ากับวิธีสาธารณะใด ๆ ที่ประกาศใน {@linkplain Object}

ดังนั้นอย่างน้อยใน java8 คุณควรใช้ @Override ในการใช้วิธีการอินเตอร์เฟส


1

Eclipse จะเพิ่ม@Overrideคำอธิบายประกอบเมื่อคุณบอกให้ "สร้างวิธีการที่ไม่ได้ดำเนินการ" ในระหว่างการสร้างคลาสที่ใช้อินเทอร์เฟซ


1

รวมทั้งปัญหาเกี่ยวกับการที่@Overrideจะช่วยให้คุณคิดว่าคุณลืมที่จะเรียกsuper.theOverridenMethod()วิธีการซึ่งจะทำให้เกิดความสับสนมาก นี่ควรจะใส บางที Java ควรเสนอ@Interfaceที่จะใช้ที่นี่ อืมแต่ทว่า Java ที่มีคุณสมบัติกึ่งภาษากึ่งท ...


3
การเรียก super เมื่อไม่ใช้งานอินเตอร์เฟสไม่ใช่สิ่งที่คุณต้องการหรือต้องการทำเสมอ บางครั้งคุณกำลังเพิ่มฟังก์ชั่น - คุณจึงเรียกมันว่า บางครั้งคุณกำลังแทนที่ฟังก์ชั่นดังนั้นคุณจึงไม่เรียกมันว่า ผู้เขียน API ควรทำเอกสารว่ามันขึ้นอยู่กับการทำงานภายในหรือไม่และสร้างสัญญาที่มีเอกสารว่าจะขยายคลาสได้อย่างเหมาะสมได้อย่างไร
lilbyrdie

1

ใน java 6 และรุ่นที่ใหม่กว่าคุณสามารถใช้@Overrideสำหรับวิธีการนำอินเตอร์เฟสไปใช้

แต่ฉันไม่คิดว่ามันสมเหตุสมผล: override หมายความว่าคุณมีวิธีการในคลาส super และคุณใช้มันในคลาสย่อย

หากคุณกำลังใช้อินเตอร์เฟซผมคิดว่าเราควรใช้@Implementหรือสิ่งอื่น @Overrideแต่ไม่ได้


0

สำหรับอินเตอร์เฟสการใช้ @Override ทำให้เกิดข้อผิดพลาดในการคอมไพล์ ดังนั้นฉันต้องลบมัน

ข้อความแสดงข้อผิดพลาด " The method getAllProducts() of type InMemoryProductRepository must override a superclass method"

นอกจากนี้ยังอ่าน " One quick fix available: Remove @Override annotation."

มันอยู่ใน Eclipse 4.6.3, JDK 1.8.0_144


0

ถ้าชั้นที่มีการดำเนินการinterfaceเป็นabstractชั้น@Overrideเป็นประโยชน์เพื่อให้มั่นใจว่าการดำเนินการเป็นสำหรับinterfaceวิธีการ; โดยไม่ต้อง ชั้นก็จะรวบรวมดีแม้ว่าลายเซ็นวิธีการดำเนินการไม่ตรงกับวิธีการประกาศใน; วิธีการที่ไม่ตรงกันจะยังคงเหมือนเดิม เอกสาร Java อ้างโดย @Zhao@Overrideabstractinterfaceinterface

วิธีการจะแทนที่หรือใช้วิธีการประกาศใน supertype

เห็นได้ชัดว่าหมายถึงabstractระดับสูงสุด; interfaceไม่สามารถเรียกว่า supertype ดังนั้นจึง@Overrideมีความซ้ำซ้อนและไม่เหมาะสมสำหรับinterfaceการใช้งานวิธีในชั้นเรียนที่เป็นรูปธรรม

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