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

ตัวอย่างเช่น สิ่งต่างๆ เช่น รถยนต์ จักรยานยนต์ มอเตอร์ไซค์ และล้อ จะแสดงเป็นคลาสและวัตถุได้ดีที่สุด แต่ความสามารถของพวกเขา เช่น "ฉันขี่ได้" "ฉันขนส่งคนได้" "ฉันยืนได้" จะถูกนำเสนอเป็นอินเทอร์เฟซได้ดีกว่า นี่คือตัวอย่างบางส่วน:
รหัส | คำอธิบาย |
---|---|
|
สอดคล้องกับความสามารถในการเคลื่อนไหว |
|
สอดคล้องกับความสามารถในการขี่ |
|
สอดคล้องกับความสามารถในการขนส่งสิ่งของ |
|
ชั้นWheel สามารถย้าย |
|
ชั้น เรียนCar สามารถเคลื่อนที่ ขี่ และขนส่งสิ่งของได้ |
|
ชั้นSkateboard เรียนสามารถเคลื่อนที่และขี่ได้ |
2. บทบาท
อินเทอร์เฟซทำให้ชีวิตของโปรแกรมเมอร์ง่ายขึ้นอย่างมาก บ่อยครั้งที่โปรแกรมมีอ็อบเจ กต์นับพัน คลาสหลายร้อยคลาส แต่มีอินเทอร์เฟซเพียงไม่กี่โหลเช่นบทบาท มีบทบาทน้อย แต่มีหลายวิธีในการรวมเข้าด้วยกัน (คลาส)
ประเด็นทั้งหมดคือคุณไม่จำเป็นต้องเขียนโค้ดสำหรับแต่ละคลาสเพื่อโต้ตอบกับคลาสอื่นๆ คุณเพียงแค่ต้องโต้ตอบกับบทบาทของพวกเขา (ส่วนต่อประสาน)
จินตนาการว่าคุณเป็นครูฝึกสัตว์เลี้ยง สัตว์เลี้ยงแต่ละตัวที่คุณทำงานด้วยสามารถมีความสามารถที่แตกต่างกันได้หลายอย่าง คุณโต้เถียงฉันมิตรกับเพื่อนบ้านว่าสัตว์เลี้ยงของใครส่งเสียงดังได้มากที่สุด ในการสะสางปัญหา คุณเพียงแค่จัดแถวสัตว์เลี้ยงทั้งหมดที่สามารถ "พูดได้" และคุณให้คำสั่งแก่พวกมัน: พูด!
คุณไม่สนใจว่าพวกมันจะเป็นสัตว์ประเภทไหนหรือมีความสามารถอะไรอีกบ้าง แม้ว่าพวกเขาจะตีลังกากลับหลังได้สามเท่าก็ตาม ในขณะนี้ คุณสนใจแต่ความสามารถในการพูดเสียงดังของพวกเขาเท่านั้น นี่คือลักษณะของโค้ด:
รหัส | คำอธิบาย |
---|---|
|
ความCanSpeak สามารถ อินเทอร์เฟซนี้เข้าใจคำสั่งถึงspeak ซึ่งหมายความว่ามีวิธีการที่สอดคล้องกัน |
|
สัตว์ที่มีคุณสมบัตินี้
เพื่ออำนวยความสะดวกในการทำความเข้าใจ เราได้ระบุชื่อชั้นเรียนเป็นภาษาอังกฤษ สิ่งนี้ได้รับอนุญาตใน Java แต่เป็นสิ่งที่ไม่พึงปรารถนาอย่างยิ่ง
|
|
แล้วเราจะให้คำสั่งแก่พวกเขาอย่างไร? |
เมื่อจำนวนชั้นเรียนในโปรแกรมของคุณถึงหลักพัน คุณจะไม่สามารถอยู่ได้หากไม่มีอินเทอร์เฟซ แทนที่จะอธิบายถึงการทำงานร่วมกันของคลาสหลายพันคลาส ก็เพียงพอแล้วที่จะอธิบายการทำงานร่วมกันของอินเทอร์เฟซไม่กี่โหล — สิ่งนี้ทำให้ชีวิตง่ายขึ้นอย่างมาก
และเมื่อรวมกับความหลากหลาย แนวทางนี้มักจะประสบความสำเร็จอย่างยอดเยี่ยม
3. default
การใช้วิธีการเชื่อมต่อ
คลาสนามธรรมสามารถมีตัวแปรและการใช้งานเมธอดได้ แต่ไม่สามารถมีหลายการสืบทอด อินเทอร์เฟซไม่สามารถมีตัวแปรหรือการนำเมธอดไปใช้ได้ แต่สามารถมีได้หลายการสืบทอด
สถานการณ์แสดงในตารางต่อไปนี้:
ความสามารถ/คุณสมบัติ | คลาสนามธรรม | อินเทอร์เฟซ |
---|---|---|
ตัวแปร | ✔ | ✖ |
การนำวิธีการไปใช้ | ✔ | ✖ |
มรดกหลายรายการ | ✖ | ✔ |
ดังนั้น โปรแกรมเมอร์บางคนจึงต้องการให้อินเทอร์เฟซมีความสามารถในการใช้งานเมธอด แต่การมีความสามารถในการเพิ่มการใช้งานเมธอดไม่ได้หมายความว่าจะถูกเพิ่มเข้าไปเสมอ เพิ่มถ้าคุณต้องการ หรือถ้าไม่มีก็อย่าเลย
นอกจากนี้ ปัญหาเกี่ยวกับการสืบทอดหลายรายการมีสาเหตุหลักมาจากตัวแปร ไม่ว่าในกรณีใด นั่นคือสิ่งที่พวกเขาตัดสินใจและทำ ตั้งแต่ JDK 8 เป็นต้นมา Java ได้แนะนำความสามารถในการเพิ่มการใช้งานเมธอดให้กับอินเทอร์เฟซ
นี่คือตารางที่อัปเดต (สำหรับ JDK 8 ขึ้นไป):
ความสามารถ/คุณสมบัติ | คลาสนามธรรม | อินเทอร์เฟซ |
---|---|---|
ตัวแปร | ✔ | ✖ |
การนำวิธีการไปใช้ | ✔ | ✔ |
มรดกหลายรายการ | ✖ | ✔ |
ตอนนี้สำหรับคลาสนามธรรมและอินเตอร์เฟส คุณสามารถประกาศเมธอดโดยมีหรือไม่มีการอิมพลีเมนต์ก็ได้ และนี่คือข่าวดี!
ในคลาสนามธรรม เมธอดที่ไม่มีการนำไปใช้ต้องนำหน้าด้วยabstract
คีย์เวิร์ด คุณไม่จำเป็นต้องเพิ่มอะไรก่อนเมธอดด้วยการนำไปใช้ ในอินเทอร์เฟซ สิ่งที่ตรงกันข้ามคือความจริง ถ้าเมธอดไม่มีการอิมพลีเมนต์ ก็ไม่ควรเพิ่มเมธอดใดๆ แต่หากมีการนำไปใช้ก็default
ต้องเพิ่มคีย์เวิร์ด
เพื่อความง่าย เรานำเสนอข้อมูลนี้ในตารางเล็กๆ ต่อไปนี้:
ความสามารถ/คุณสมบัติ | คลาสนามธรรม | อินเทอร์เฟซ |
---|---|---|
วิธีการที่ไม่มีการนำไปใช้ | abstract |
– |
วิธีการพร้อมการใช้งาน | – | default |
ปัญหา
การใช้อินเตอร์เฟสที่มีเมธอดสามารถลดความซับซ้อนของลำดับชั้นของคลาสขนาดใหญ่ได้อย่างมาก ตัวอย่างเช่น บทคัดย่อInputStream
และOutputStream
คลาสสามารถประกาศเป็นส่วนต่อประสานได้! สิ่งนี้ทำให้เราใช้งานได้บ่อยขึ้นและสะดวกขึ้นมาก
แต่มีคลาส Java นับสิบล้าน (พันล้าน?) ในโลก และถ้าคุณเริ่มเปลี่ยนไลบรารี่มาตรฐาน คุณอาจทำบางอย่างพัง ชอบทุกอย่าง! 😛
เพื่อไม่ให้โปรแกรมและไลบรารีที่มีอยู่ทำงานผิดพลาดโดยไม่ได้ตั้งใจ จึงมีการตัดสินใจว่าการนำเมธอดไปใช้ในอินเทอร์เฟซจะมีลำดับการสืบทอดที่ต่ำที่สุด
ตัวอย่างเช่น หากอินเทอร์เฟซหนึ่งสืบทอดอินเทอร์เฟซอื่นที่มีเมธอด และอินเทอร์เฟซแรกประกาศเมธอดเดียวกันแต่ไม่มีการนำไปใช้ ดังนั้นการนำเมธอดจากอินเทอร์เฟซที่สืบทอดมาไปใช้จะไม่ไปถึงอินเทอร์เฟซที่สืบทอดมา ตัวอย่าง:
interface Pet
{
default void meow()
{
System.out.println("Meow");
}
}
interface Cat extends Pet
{
void meow(); // Here we override the default implementation by omitting an implementation
}
class Tom implements Cat
{
}
รหัสจะไม่คอมไพล์เนื่องจากTom
คลาสไม่ได้ใช้meow()
เมธอด
GO TO FULL VERSION