ควรประกาศวิธีการในอินเทอร์เฟซ Java ที่มีหรือไม่มีตัวแก้ไขการเข้าถึงสาธารณะหรือไม่?


292

ควรประกาศวิธีการในอินเทอร์เฟซ Java ด้วยpublicตัวดัดแปลงการเข้าถึงหรือไม่?

แน่นอนว่าในทางเทคนิคแล้วมันไม่สำคัญ วิธีการเรียนที่ใช้อยู่เสมอinterface publicแต่การประชุมที่ดีกว่าคืออะไร?

Java เองนั้นไม่สอดคล้องกันในเรื่องนี้ ดูตัวอย่างCollectionเทียบComparableหรือเทียบกับFutureScriptEngine


22
มันไม่ดีเพราะการเขียนเป็นสาธารณะหมายความว่ามันอาจไม่ใช่แบบสาธารณะ
Pacerier

8
คุณควรหลีกเลี่ยงไวยากรณ์ที่ซ้ำซ้อนของรูปแบบใด ๆ
มาร์ควิสแห่ง Lorne

3
@Pacerier ในขณะที่ฉันยอมรับว่ามันไม่ดีที่จะใช้publicในบริบทนี้วิธีการเริ่มต้นส่วนติดต่อสามารถตอนนี้ (กับ java 9) เป็นส่วนตัว ฉันแนะนำให้คุณลบความคิดเห็นของคุณเนื่องจากล้าสมัยแล้ว
aioobe

2
ใช่สิ่งที่อาจมีการเปลี่ยนแปลงในชวา 9. "การเขียนเป็นสาธารณะหมายความว่ามันสามารถจะไม่ใช่แบบสาธารณะ" เนื่องจากว่าที่น่าจะเป็นไปได้ใน Java 9 publicเรื่องนี้ตอนนี้อยู่ในประโยชน์ของจริงเขียนออก
MC Emperor

คำตอบ:


334

JLSทำให้เห็นได้ชัดนี้:

มันได้รับอนุญาต แต่ท้อแท้เป็นเรื่องของสไตล์เพื่อระบุซ้ำซ้อนpublicและ / หรือabstractปรับปรุงสำหรับวิธีการประกาศในอินเทอร์เฟซ


6
ลิงค์ JLS ด้านบนสำหรับ Java 7 ในขณะที่ฉันอ่าน หลังจากการแสดงความคิดเห็นเกี่ยวกับ Java 9 ช่วยให้วิธีการที่ไม่ใช่ที่สาธารณะฉันแค่อยากจะยืนยันว่าการใช้ถ้อยคำที่คล้ายกันมากยังคงมีอยู่สำหรับSE9 JLS ( publicส่วนหนึ่งเหมือนกันand/or abstractส่วนที่ถูกดร็อป)
OzgurH

3
ยังคงเป็นจริงในSE11 JLS
Ortomala Lokni


44

ตัวแก้ไขสาธารณะควรถูกละเว้นในส่วนต่อประสาน Java (ตามความเห็นของฉัน)

เนื่องจากมันไม่ได้เพิ่มข้อมูลเพิ่มเติมใด ๆ มันเพียงดึงความสนใจออกไปจากสิ่งที่สำคัญ

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

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}

3
คุณมีลิงค์ไปยังไกด์นำเที่ยวดังกล่าวหรือไม่?
Benno Richters

9
ความสอดคล้องเป็นสิ่งที่สำคัญที่สุดและเป็นคำตอบของคำถามประเภทนี้ถึง 99%
SCdF

ตกลงอีกครั้ง: ความสอดคล้อง บางสิ่งบางอย่างสำหรับผู้ชายเอกสารมาตรฐานการเข้ารหัสของคุณ :)
JeeBee

2
Bno: ตัวอย่างหนึ่งคือข้อกำหนดภาษา Java อีกหนึ่งคือ Checkstyle
Rasmus Faber

9

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

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

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

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

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

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


7

ด้วยการแนะนำของprivate, static, defaultการปรับเปลี่ยนวิธีการอินเตอร์เฟซในชวา 8/9 สิ่งที่ได้รับความซับซ้อนมากขึ้นและฉันมักจะคิดว่าการประกาศเต็มสามารถอ่านได้มากขึ้น (ความต้องการ Java 9 เพื่อรวบรวม):

public interface MyInterface {

    //minimal
    int CONST00 = 0;
    void method00();
    static void method01() {}
    default void method02() {}
    private static void method03() {}
    private void method04() {}

    //full
    public static final int CONST10 = 0;
    public abstract void method10();
    public static void method11() {}
    public default void method12() {}
    private static void method13() {}
    private void method14() {}

}

5

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

ที่แย่ที่สุดที่ฉันเห็นคือส่วนต่อประสานที่มีวิธีการประกาศabstract...


5

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

ดังนั้นฉันไม่แน่ใจว่าสิ่งใดดีที่สุด แต่สิ่งหนึ่งที่ฉันไม่ชอบคือการใช้public abstractวิธีการอินเทอร์เฟซ Eclipse ทำเช่นนี้บางครั้งเมื่อทำการเปลี่ยนสถานะใหม่ด้วย "Extract Interface"


2
แต่เฉพาะในกรณีที่คุณทำเครื่องหมายในช่องทำเครื่องหมายทั้งสองประกาศวิธีสาธารณะเป็นนามธรรม
MetroidFan2002

4

publicฉันมักจะเขียนสิ่งที่ผมจะใช้ถ้ามีอินเตอร์เฟซที่ไม่ได้และผมเขียนการดำเนินงานโดยตรงคือผมจะใช้


6
คุณจะประกาศวิธีการเชื่อมต่อทั้งหมดอย่างชัดเจนหรือไม่?
Dan Dyer

4
มันเป็นอินเตอร์เฟสไม่ใช่คลาสนามธรรม ในส่วนที่เกี่ยวกับ 'สาธารณะ' มันเป็นตัวละคร 7 ตัวที่คุณพิมพ์เมื่อคุณคิดถึงมันเรื่องใหญ่! และมันก็เป็นสิ่งที่กำหนดไว้ในการดำเนินการเช่นกันซึ่งก็คือ +1 สำหรับความสอดคล้องทำให้สมดุล -1 สำหรับความซ้ำซ้อน
JeeBee

3

ฉันชอบการกระโดดข้ามมันฉันอ่านบางที่อินเตอร์เฟซโดยค่าเริ่มต้นและpublicabstract

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

อย่างไรก็ตามฉันคิดว่าควรละเว้นข้อมูลที่ซ้ำซ้อน


1
เพียงชี้แจงให้ชัดเจนหากคุณไม่publicใช้ตัวแก้ไขการเข้าถึงในการประกาศอินเทอร์เฟซก็จะไม่เป็นสาธารณะและเป็นนามธรรมโดยค่าเริ่มต้น docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad

3

ฉันไม่เห็นด้วยกับคำตอบที่ได้รับความนิยมว่าการมีสาธารณะหมายถึงว่ามีตัวเลือกอื่น ๆ ดังนั้นจึงไม่ควรอยู่ที่นั่น ความจริงก็คือตอนนี้กับ Java 9 และเกินกว่าจะมีตัวเลือกอื่น ๆ

ฉันคิดว่า Java ควรบังคับ / ต้องการให้ 'สาธารณะ' แทน ทำไม? เนื่องจากการไม่มีตัวแก้ไขหมายถึงการเข้าถึง 'แพ็คเกจ' ในที่อื่นและการมีสิ่งนี้เป็นกรณีพิเศษคือสิ่งที่นำไปสู่ความสับสน หากคุณเพียงแค่ทำให้มันเป็นข้อผิดพลาดในการคอมไพล์ด้วยข้อความที่ชัดเจน (เช่น "การเข้าถึงแพ็คเกจไม่ได้รับอนุญาตในอินเทอร์เฟซ") เราจะกำจัดความคลุมเครือที่เห็นได้ชัดว่ามีตัวเลือกที่จะไม่แนะนำ

สังเกตถ้อยคำปัจจุบันได้ที่: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"วิธีการในส่วนของอินเทอร์เฟซอาจถูกประกาศเป็นแบบสาธารณะหรือแบบ ส่วนตัว (§6.6) หากไม่ได้กำหนดตัวแก้ไขการเข้าถึงวิธีนั้นจะเป็นแบบสาธารณะโดยปริยายมันได้รับอนุญาต แต่ท้อแท้เป็นเรื่องของสไตล์ โมดิฟายเออร์สำหรับการประกาศเมธอดในอินเตอร์เฟส "

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


2

เหตุผลสำหรับวิธีการในการเชื่อมต่อโดยเป็นค่าเริ่มต้นสาธารณะและนามธรรมดูเหมือนค่อนข้างสมเหตุสมผลและชัดเจนสำหรับฉัน

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

การเพิ่มโมเดอเรเตอร์เหล่านี้ในโค้ดของคุณนั้นซ้ำซ้อนและไร้ประโยชน์และสามารถนำไปสู่ข้อสรุปว่าคุณขาดความรู้และ / หรือความเข้าใจพื้นฐานของ Java


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

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

1

มันเป็นอัตวิสัยทั้งหมด ฉันไม่ได้publicแก้ไขตัวแก้ไขที่ซ้ำซ้อนเพราะดูเหมือนว่าจะรก ดังที่กล่าวไว้โดยคนอื่น ๆ - ความสม่ำเสมอเป็นกุญแจสำคัญในการตัดสินใจนี้

เป็นที่น่าสนใจที่จะทราบว่านักออกแบบภาษา C # ตัดสินใจบังคับใช้สิ่งนี้ การประกาศเมธอดอินเตอร์เฟสเป็น public ใน C # เป็นข้อผิดพลาดในการคอมไพล์ ความสอดคล้องอาจไม่สำคัญในภาษาต่าง ๆ ดังนั้นฉันเดาว่านี่ไม่เกี่ยวข้องกับ Java โดยตรง


-9

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


8
ฉันต้องไม่เห็นด้วยกับข้อความที่ว่าไม่มีใครอ่านต้นฉบับ ฉันคิดว่าผู้คนจำนวนมากใช้เช่น F3 ใน Eclipse เพื่อซูมเข้าไปในโค้ด เครื่องมืออย่าง Maven มีตัวเลือกให้ดาวน์โหลดแหล่งข้อมูลไม่ใช่เพียง JavaDoc ด้วยเหตุผล
Benno Richters

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