จะใช้เมื่อใด: วิธีการเริ่มต้นของอินเตอร์เฟส Java 8+, กับวิธีที่เป็นนามธรรม


540

Java 8 ช่วยให้การเริ่มต้นใช้งานวิธีการในการเชื่อมต่อที่เรียกว่าวิธีการเริ่มต้น

ฉันสับสนระหว่างเมื่อไรที่ฉันจะใช้ประเภทinterface default methodนั้นแทนที่จะเป็นabstract class(พร้อมabstract method(s))

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


38
บางทีคุณยังไม่สามารถมีฟิลด์, เมธอดส่วนตัว, ฯลฯ ในอินเทอร์เฟซ, ในขณะที่คุณอยู่ในคลาสนามธรรม?
sp00m

2
ฉันเคยสงสัยเกี่ยวกับเรื่องนี้มาก่อนตอนนี้ฉันชัดเจนแล้วขอขอบคุณ @Narendra Pathai ฉันต้องการเพิ่มลิงค์ของหัวข้ออื่นที่คุณถามเกี่ยวกับหัวข้อเดียวกันเนื่องจากทั้งสองข้อนี้เป็นข้อสงสัยของฉัน stackoverflow.com/questions/19998309/…
Ashutosh Ranjan

คุณสามารถหาโพสต์ที่ดีได้ที่นี่: blog.codefx.org/java/everything-about-default-methods
Fabri Pautasso

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

@DaBlick คุณไม่สามารถแก้ปัญหาสถานะในอินเทอร์เฟซผ่าน HashMap ได้ เช่นถ้าคุณต้องการ class Foo ที่มี int a, b, String c และคุณต้องการให้รัฐสร้างชื่อ HashMap </ * ของวัตถุ Foo * / String, / * แผนที่ของฟิลด์ * / Hashmap </ * ชื่อเฉพาะฟิลด์ * / String, / * ค่าฟิลด์ * / Object >> แผนที่ . เมื่อคุณต้องการ "สร้างอินสแตนซ์" คลาสเชิงทฤษฎี Foo คุณมีเมธอด, อินสแตนซ์ (String nameOfFoo) ซึ่งทำ map.put (nameOfFoo, ฟิลด์) โดยที่เขตข้อมูลคือ HashMap <String, Object> fields.put ("a", ใหม่ int ( "5")); fields.put ("b", int ใหม่ ("6")); fields.put ("c", "blah"));
George Xavier

คำตอบ:


307

มีคลาสนามธรรมมากกว่าการใช้วิธีการเริ่มต้น (เช่นสถานะส่วนตัว) แต่ใน Java 8 ทุกครั้งที่คุณมีตัวเลือกคุณควรไปกับdefaultเมธอดdefender (aka. ) ในอินเทอร์เฟซ

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

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

แรงจูงใจดั้งเดิมในการแนะนำdefaultวิธีการกับ Java 8 คือความปรารถนาที่จะขยายส่วนต่อประสาน Collections Framework ด้วยวิธี lambda-oriented โดยไม่ทำลายการใช้งานที่มีอยู่ แม้ว่าสิ่งนี้จะเกี่ยวข้องกับผู้แต่งห้องสมุดสาธารณะมากกว่า แต่คุณอาจพบว่าคุณลักษณะเดียวกันนี้มีประโยชน์สำหรับโครงการของคุณเช่นกัน คุณมีสถานที่รวมศูนย์แห่งหนึ่งที่จะเพิ่มความสะดวกสบายใหม่และคุณไม่ต้องพึ่งพาลักษณะลำดับชั้นของส่วนที่เหลือ


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

3
การใช้ Abstract Classes ใน Java 8 ยุคที่ฉันสามารถเห็นคือการกำหนดเขตข้อมูลที่ไม่สิ้นสุด ในส่วนต่อประสานฟิลด์จะเป็นค่าเริ่มต้นสุดท้ายดังนั้นคุณจะไม่สามารถเปลี่ยนแปลงได้เมื่อได้รับมอบหมาย
Anuroop

7
@Anuroop ไม่เพียง แต่โดยค่าเริ่มต้น --- นั่นเป็นตัวเลือกเท่านั้น อินเทอร์เฟซไม่สามารถประกาศสถานะอินสแตนซ์ซึ่งเป็นสาเหตุให้คลาสนามธรรมอยู่ที่นี่
Marko Topolnik

2
@PhilipRego วิธีการแบบนามธรรมไม่เรียกสิ่งใดเพราะไม่มีการนำไปใช้ วิธีการดำเนินการในชั้นเรียนสามารถเข้าถึงสถานะของชั้นเรียน (ตัวแปรอินสแตนซ์) อินเทอร์เฟซไม่สามารถประกาศได้ดังนั้นวิธีการเริ่มต้นจึงไม่สามารถเข้าถึงได้ พวกเขาจะต้องพึ่งพาชั้นเรียนที่ให้วิธีการดำเนินการที่เข้าถึงรัฐ
Marko Topolnik

2
Marko Topolnik คำตอบของคุณตายไปแล้ว แต่ฉันอยากจะแนะนำการอัปเดตสำหรับคำตอบของคุณ คุณอาจต้องการเพิ่มความสวยงามของวิธีการเริ่มต้นคือถ้าอินเทอร์เฟซเพิ่มวิธีการเริ่มต้นใหม่การใช้งานก่อนหน้าของอินเทอร์เฟซนั้นจะไม่แตก สิ่งนี้ไม่เป็นความจริงก่อนหน้า Java 8
hfontanez

125

มีความแตกต่างทางเทคนิคเล็กน้อย คลาสนามธรรมยังสามารถทำได้มากกว่าเมื่อเปรียบเทียบกับอินเตอร์เฟส Java 8:

  1. คลาสนามธรรมสามารถมีตัวสร้าง
  2. คลาสนามธรรมมีโครงสร้างมากขึ้นและสามารถเก็บสถานะ

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


20
คำตอบนี้ถูกต้องและเหมาะสมโดยเฉพาะอย่างยิ่ง "แนวคิดวัตถุประสงค์หลักของวิธีการป้องกันคือความเข้ากันได้ย้อนหลัง"
ลอง

1
@UnKnown หน้านี้ให้ข้อมูลเชิงลึกมากขึ้น: docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
bernie

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

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

3
@Anuroop ฉันไม่ได้อธิบายpublic static finalฟิลด์ของอินเทอร์เฟซว่า "state" staticส่วนหนึ่งหมายความว่า the're ไม่เกี่ยวข้องกับอินสแตนซ์โดยเฉพาะอย่างยิ่งที่ทุกคน พวกเขาจะได้รับมอบหมายในการเริ่มชั้นเรียนซึ่งไม่ได้เป็นเช่นเดียวกับหลังการสร้างอินสแตนซ์
geronimo

65

นี้จะถูกอธิบายไว้ในบทความ คิดถึงforEachคอลเลคชัน

List<?> list = 
list.forEach(…);

forEach ยังไม่ได้ประกาศโดยjava.util.Listหรือ java.util.Collectionอินเทอร์เฟซ ทางออกหนึ่งที่เห็นได้ชัดคือเพียงเพิ่มวิธีการใหม่ไปยังอินเทอร์เฟซที่มีอยู่และจัดให้มีการดำเนินการตามที่จำเป็นใน JDK อย่างไรก็ตามเมื่อเผยแพร่แล้วมันเป็นไปไม่ได้ที่จะเพิ่มวิธีการในส่วนต่อประสานโดยไม่ทำให้การใช้งานที่มีอยู่นั้นพัง

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


1
'มันเป็นไปไม่ได้ที่จะเพิ่มวิธีการในอินเทอร์เฟซโดยไม่ทำให้การดำเนินการที่มีอยู่' - ใช่หรือไม่
Andrey Chaschev

26
@AndreyChaschev หากคุณเพิ่มวิธีการใหม่ในอินเทอร์เฟซผู้ดำเนินการทุกคนจะต้องใช้วิธีการใหม่นั้น ดังนั้นจึงแบ่งการใช้งานที่มีอยู่
Marko Topolnik

4
@MarkoTopolnik ขอบคุณที่พลาด เพียงกล่าวถึงมีวิธีที่จะหลีกเลี่ยงบางส่วน - โดยการนำเสนอวิธีการนี้ในการใช้นามธรรมเริ่มต้น สำหรับตัวอย่างนี้นี้จะได้รับการขว้างปาAbstractList::forEach UnsupportedOperationException
Andrey Chaschev

3
@AndreyChaschev ใช่นั่นเป็นวิธีเก่า (khm ... เป็นวิธีปัจจุบัน :) โดยมีข้อบกพร่องที่ จำกัด ผู้ดำเนินการเพื่อสืบทอดเดียวจากการใช้นามธรรมให้
Marko Topolnik

ฉันจะไม่หยุดถ้ามันเกิดขึ้นก่อนเวลาการใช้งานทั้งหมดรวมถึงวิธีการนั้น ซึ่งไม่น่าเป็นไปได้ แต่เป็นไปได้
George Xavier

19

ทั้งสองนี้แตกต่างกันมาก:

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

และคลาสนามธรรมเป็นมรดกประเภทปกติมันเป็นคลาสปกติที่มีจุดประสงค์เพื่อขยาย


18

ตามที่อธิบายไว้ในนี้บทความ

คลาสนามธรรมกับอินเตอร์เฟสใน Java 8

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

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


ฉันเชื่อว่าคลาสนามธรรมมีตัวสร้างซึ่งสามารถกำหนดได้แตกต่างจากอินเทอร์เฟซ ใน Java 8 พวกเขาทั้งสองต่างกันเนื่องจากเรื่องนี้
Hemanth Peela

1
ทำไมคลาสนามธรรมมีคอนสตรัคเตอร์ถ้ามันไม่สามารถสร้างอินสแตนซ์ได้?
George Xavier

เราสามารถเรียก super () จากคลาสเด็กซึ่งจะเรียกคอนสตรัคเตอร์ของคลาสนามธรรมซึ่งจะส่งผลต่อสถานะของคลาสนามธรรม
Sujay Mohan

14

เกี่ยวกับแบบสอบถามของคุณ

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

เอกสารจาวาให้คำตอบที่สมบูรณ์แบบ

คลาสนามธรรมเมื่อเปรียบเทียบกับอินเทอร์เฟซ:

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

อย่างไรก็ตามด้วยคลาสนามธรรมคุณสามารถประกาศเขตข้อมูลที่ไม่คงที่และสุดท้ายและกำหนดวิธีสาธารณะสาธารณะการป้องกันและส่วนตัว

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

กรณีใช้งานสำหรับแต่ละกรณีมีการอธิบายไว้ในโพสต์ด้านล่าง SE:

อะไรคือความแตกต่างระหว่างอินเตอร์เฟสและคลาสนามธรรม?

คลาสนามธรรมยังมีประโยชน์ในสถานการณ์นั้นหรือไม่?

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


ตอนนี้อินเตอร์เฟซที่มีวิธีการส่วนตัวเกินไปhowtodoinjava.com/java9/java9-private-interface-methods
valijon

13

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

  1. วิธีการเริ่มต้นได้หมดสิ้นไปสู่รูปแบบคลาสสิกของอินเทอร์เฟซและคลาสของคู่หูที่ใช้วิธีการส่วนใหญ่หรือทั้งหมดในอินเทอร์เฟซนั้น Collection and AbstractCollectionตัวอย่างคือ ตอนนี้เราควรใช้วิธีการต่าง ๆ ในส่วนต่อประสานเพื่อให้การทำงานเริ่มต้น คลาสที่ใช้อินเตอร์เฟสมีตัวเลือกเพื่อแทนที่เมธอดหรือสืบทอดการใช้ดีฟอลต์
  2. interface evolutionควบคุมการใช้งานที่สำคัญของวิธีการเริ่มต้นคือ สมมติว่าฉันมีคลาสบอลเป็น:

    public class Ball implements Collection { ... }

ตอนนี้ใน Java 8 ได้มีการเปิดตัวฟีเจอร์ใหม่ ๆ เราสามารถรับสตรีมได้โดยใช้streamวิธีการที่เพิ่มเข้าไปในส่วนต่อประสาน หากstreamไม่ใช่วิธีการเริ่มต้นการใช้งานทั้งหมดสำหรับCollectionส่วนต่อประสานจะใช้งานไม่ได้เนื่องจากไม่ได้ใช้วิธีการใหม่นี้ การเพิ่มวิธีการที่ไม่ใช่ค่าเริ่มต้นให้กับส่วนต่อประสานนั้นไม่ใช่source-compatibleเพิ่มวิธีการที่ไม่ใช่ค่าเริ่มต้นให้กับอินเตอร์เฟซที่ไม่ได้เป็น

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


9

วิธีการเริ่มต้นในอินเตอร์เฟซ Java ช่วยให้วิวัฒนาการอินเตอร์เฟซ

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

วิธีการคงที่ไม่ซ้ำกับชั้นเรียน วิธีการเริ่มต้นไม่ซ้ำกับอินสแตนซ์ของคลาส

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

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

เพิ่มเติมเกี่ยวกับหัวข้อที่นี่


7

แม้ว่ามันจะเป็นคำถามเก่า ๆ ก็ตามฉันก็ให้ความเห็นด้วยเช่นกัน

  1. คลาสนามธรรม:ภายในคลาสนามธรรมเราสามารถประกาศตัวแปรอินสแตนซ์ซึ่งจำเป็นสำหรับคลาสลูก

    อินเทอร์เฟซ:อินเทอร์เฟซภายในตัวแปรทุกตัวเป็นแบบสแตติกสาธารณะและสุดท้ายเราไม่สามารถประกาศตัวแปรอินสแตนซ์ได้

  2. คลาสนามธรรม: คลาสนามธรรมสามารถพูดคุยเกี่ยวกับสถานะของวัตถุ

    อินเตอร์เฟส:ส่วนต่อประสานไม่สามารถพูดคุยเกี่ยวกับสถานะของวัตถุ

  3. ระดับนามธรรม:ภายในชั้นนามธรรมเราสามารถประกาศก่อสร้าง

    อินเทอร์เฟซ:อินเทอร์เฟซภายในเราไม่สามารถประกาศตัวสร้างตามวัตถุประสงค์ของตัว
    สร้างคือการเริ่มต้นตัวแปรอินสแตนซ์ ถ้าเราไม่สามารถมีตัวแปรอินสแตนซ์ในอินเทอร์เฟซได้

  4. ระดับนามธรรม:ภายในชั้นนามธรรมเราสามารถประกาศตัวอย่างและบล็อกคงที่

    อินเทอร์เฟซ:อินเทอร์เฟซไม่สามารถมีอินสแตนซ์และบล็อกแบบคงที่

  5. ระดับนามธรรม: ชั้นนามธรรมไม่สามารถอ้างถึงการแสดงออกแลมบ์ดา

    การเชื่อมต่อ: การเชื่อมต่อด้วยวิธีนามธรรมเดียวสามารถอ้างถึงการแสดงออกแลมบ์ดา

  6. ระดับนามธรรม : ภายในชั้นนามธรรมเราสามารถแทนที่วิธีการ OBJECT CLASS

    อินเทอร์เฟซ:เราไม่สามารถแทนที่เมธอด OBJECT CLASS ภายในอินเทอร์เฟซ

ฉันจะจบในหมายเหตุที่:

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


5

กฎRemi Foraxคือคุณไม่ได้ออกแบบคลาส Abstract คุณออกแบบแอปของคุณมีอินเตอร์เฟซ สิ่งใดคือเวอร์ชันของ Java สิ่งที่เป็นภาษา มันได้รับการสนับสนุนโดยหลักการแยกส่วนฉัน nterfaceในSOL I Dหลักการ

คุณสามารถใช้คลาสนามธรรมในภายหลังเพื่อแยกรหัส ขณะนี้ใช้ Java 8 คุณสามารถทำได้โดยตรงในส่วนต่อประสาน นี่คือสิ่งอำนวยความสะดวกไม่มาก


2

ควรจะใช้ส่วนต่อประสานกับวิธีการเริ่มต้นเมื่อใดและควรใช้คลาสนามธรรมเมื่อใด

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

ข้อเท็จจริงและข้อ จำกัด :

1 พฤษภาคมสามารถประกาศได้เฉพาะภายในส่วนต่อประสานและไม่อยู่ในคลาสหรือระดับนามธรรม

2- ต้องจัดให้มีร่างกาย

3- จะไม่ถือว่าเป็นนามธรรมเป็นวิธีการปกติอื่น ๆ ที่ใช้ในอินเทอร์เฟซ


1

ใน Java 8 อินเตอร์เฟสดูเหมือนคลาสนามธรรมแม้ว่าอาจมีความแตกต่างบางอย่างเช่น:

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

2) ความแตกต่างทางความหมายระหว่างอินเตอร์เฟสกับเมธอดดีฟอลต์และคลาส abstract คือคุณสามารถกำหนด constructors ภายในคลาส abstractแต่คุณไม่สามารถกำหนด constructor ภายในอินเตอร์เฟสใน Java


ฉันเห็นด้วยกับ # 2 แต่สำหรับ # 1 คุณไม่สามารถใช้ส่วนต่อประสานและทำให้มีสถานะผ่านคลาสการใช้งานหรือไม่
George Xavier

0

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

อย่างไรก็ตามวิธีการในคลาสนามธรรมควรให้การใช้งานที่มีความหมายซึ่งคลาสย่อยใด ๆ ควรแทนที่หากจำเป็นเพื่อแทนที่การทำงานทั่วไป


0

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

มิฉะนั้นถ้าคุณเพิ่มการใช้งานอินเทอร์เฟซคุณกำลังฝ่าฝืนกฎหมายพื้นฐานว่าทำไมอินเทอร์เฟซที่ถูกเพิ่มเข้ามาตั้งแต่แรกJava เป็นภาษาที่สืบทอดเดี่ยวซึ่งแตกต่างจาก C ++ ซึ่งอนุญาตให้มีหลายมรดก อินเทอร์เฟซให้ประโยชน์ในการพิมพ์ที่มาพร้อมกับภาษาที่รองรับการสืบทอดหลายรายการโดยไม่แนะนำปัญหาที่มาพร้อมกับการสืบทอดหลายรายการ

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

class MyObject extends String implements Runnable, Comparable { ... }

MyObject สืบทอดการใช้งานเพียงครั้งเดียว แต่ได้รับการสืบทอดสามสัญญา

Java ส่งผ่านการสืบทอดหลายการใช้งานเนื่องจากการสืบทอดหลายการใช้งานมาพร้อมกับโฮสต์ของปัญหาที่มีหนามซึ่งอยู่นอกขอบเขตของคำตอบนี้ อินเทอร์เฟซถูกเพิ่มเข้ามาเพื่ออนุญาตการสืบทอดหลายสัญญา (อินเทอร์เฟซ aka) โดยไม่มีปัญหาของการสืบทอดหลายการใช้งาน

เพื่อสนับสนุนประเด็นของฉันนี่คือข้อความจาก Ken Arnold และ James Gosling จากหนังสือThe Java Programming Language, รุ่นที่ 4 :

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


-1

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

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

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