คำตอบสั้น ๆ คือปลอดภัยถ้าใช้อย่างปลอดภัย :)
คำตอบที่น่ากลัว: บอกฉันว่าคุณหมายถึงอะไรจากลักษณะและบางทีฉันอาจจะให้คำตอบที่ดีกว่า :)
ในความร้ายแรงคำว่า "ลักษณะ" ไม่ได้กำหนดไว้อย่างชัดเจน นักพัฒนา Java หลายคนคุ้นเคยกับลักษณะที่แสดงออกมาใน Scala มากที่สุด แต่ Scala ยังห่างไกลจากภาษาแรกที่มีลักษณะไม่ว่าจะในชื่อหรือผล
ตัวอย่างเช่นใน Scala ลักษณะจะเป็นสถานะ (สามารถมีvar
ตัวแปรได้) ในป้อมปราการพวกเขาเป็นพฤติกรรมที่บริสุทธิ์ อินเทอร์เฟซของ Java กับเมธอดดีฟอลต์ไม่มีสถานะ นี่หมายความว่าพวกเขาไม่ใช่ลักษณะ? (คำแนะนำ: นั่นเป็นคำถามหลอกลวง)
อีกครั้งใน Scala ลักษณะจะประกอบขึ้นจากการทำให้เป็นเส้นตรง ถ้าคลาสA
ขยายลักษณะX
และY
ลำดับที่X
และY
ผสมจะกำหนดว่าความขัดแย้งระหว่างX
และอย่างไรY
ได้รับการแก้ไข ใน Java ไม่มีกลไกเชิงเส้นตรงนี้ (บางส่วนถูกปฏิเสธเนื่องจาก "ไม่เหมือน Java" เกินไป)
เหตุผลใกล้เคียงสำหรับการเพิ่มวิธีการเริ่มต้นในอินเทอร์เฟซคือการสนับสนุน วิวัฒนาการของอินเทอร์เฟซแต่เราทราบดีว่าเรากำลังก้าวไปไกลกว่านั้น ไม่ว่าคุณจะพิจารณาว่าเป็น "วิวัฒนาการของอินเทอร์เฟซ ++" หรือ "ลักษณะ -" เป็นเรื่องของการตีความส่วนบุคคล ดังนั้นเพื่อตอบคำถามของคุณเกี่ยวกับความปลอดภัย ... ตราบใดที่คุณยึดติดกับสิ่งที่กลไกนั้นสนับสนุนจริง ๆ แทนที่จะพยายามที่จะยืดอกไปสู่สิ่งที่มันไม่รองรับคุณก็น่าจะสบายดี
เป้าหมายในการออกแบบที่สำคัญคือจากมุมมองของไคลเอนต์ของอินเทอร์เฟซวิธีการเริ่มต้นควรแยกไม่ออกจากวิธีการเชื่อมต่อแบบ "ปกติ" ดังนั้นค่าเริ่มต้นของวิธีการจึงน่าสนใจสำหรับผู้ออกแบบและผู้ใช้งานอินเทอร์เฟซเท่านั้น
นี่คือกรณีการใช้งานบางส่วนที่อยู่ในเป้าหมายการออกแบบ:
วิวัฒนาการของอินเทอร์เฟซ ที่นี่เรากำลังเพิ่มวิธีการใหม่ให้กับอินเทอร์เฟซที่มีอยู่ซึ่งมีการใช้งานเริ่มต้นที่สมเหตุสมผลในแง่ของวิธีการที่มีอยู่บนอินเทอร์เฟซนั้น ตัวอย่างจะเป็นการเพิ่มforEach
วิธีการCollection
โดยที่การใช้งานเริ่มต้นถูกเขียนในรูปแบบของiterator()
วิธีการ
วิธี "ไม่บังคับ" ในที่นี้ผู้ออกแบบอินเทอร์เฟซกล่าวว่า "ผู้ใช้ไม่จำเป็นต้องใช้วิธีนี้หากพวกเขาเต็มใจที่จะอยู่กับข้อ จำกัด ในฟังก์ชันการทำงานที่เกี่ยวข้อง" ตัวอย่างเช่นIterator.remove
ได้รับค่าเริ่มต้นซึ่งพ่นUnsupportedOperationException
; เนื่องจากการใช้งานส่วนใหญ่Iterator
มีพฤติกรรมนี้อยู่แล้วค่าเริ่มต้นจึงทำให้วิธีนี้เป็นทางเลือก (หากพฤติกรรมจากAbstractCollection
ถูกแสดงเป็นค่าเริ่มต้นCollection
เราอาจทำเช่นเดียวกันสำหรับวิธีการกลายพันธุ์)
วิธีการอำนวยความสะดวก วิธีเหล่านี้เป็นวิธีการที่เคร่งครัดเพื่อความสะดวกโดยทั่วไปจะใช้อีกครั้งในแง่ของวิธีการที่ไม่ใช่ค่าเริ่มต้นในคลาส logger()
วิธีการในตัวอย่างแรกของคุณเป็นภาพที่เหมาะสมนี้
combinators นี่คือวิธีการจัดองค์ประกอบที่สร้างอินสแตนซ์อินเทอร์เฟซใหม่ตามอินสแตนซ์ปัจจุบัน ตัวอย่างเช่นวิธีการPredicate.and()
หรือComparator.thenComparing()
ตัวอย่างของตัวผสม
หากคุณจัดเตรียมการใช้งานเริ่มต้นคุณควรระบุข้อกำหนดบางอย่างสำหรับค่าเริ่มต้น (ใน JDK เราใช้@implSpec
แท็ก javadoc สำหรับสิ่งนี้) เพื่อช่วยผู้ใช้ในการทำความเข้าใจว่าพวกเขาต้องการแทนที่เมธอดหรือไม่ ค่าเริ่มต้นบางอย่างเช่นวิธีการอำนวยความสะดวกและตัวรวมพลังแทบจะไม่ถูกแทนที่ อื่น ๆ เช่นวิธีการทางเลือกมักจะถูกแทนที่ คุณต้องระบุข้อมูลจำเพาะที่เพียงพอ (ไม่ใช่แค่เอกสารประกอบ) เกี่ยวกับสิ่งที่สัญญาเริ่มต้นที่จะทำดังนั้นผู้ดำเนินการจึงสามารถตัดสินใจได้อย่างสมเหตุสมผลว่าพวกเขาจำเป็นต้องลบล้างสิ่งนั้นหรือไม่