1. ความสามารถ

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

คลาสมักจะจำลองวัตถุเฉพาะ ส่วนต่อประสานสอดคล้องกับออบเจ็กต์น้อยลง และมากขึ้นตามความสามารถหรือบทบาทของอ็อบเจ็กต์

สาระสำคัญของอินเทอร์เฟซ

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

รหัส คำอธิบาย
interface CanMove
{
   void move(String newLocation);
}
สอดคล้องกับความสามารถในการเคลื่อนไหว
interface Rideable
{
   void ride(Passenger passenger);
}
สอดคล้องกับความสามารถในการขี่
interface CanTransport
{
   void addStuff(Object stuff);
   Object removeStuff();
}
สอดคล้องกับความสามารถในการขนส่งสิ่งของ
class Wheel implements CanMove
{
   ...
}
ชั้นWheelสามารถย้าย
class Car implements CanMove, Rideable, CanTransport
{
   ...
}
ชั้น เรียนCarสามารถเคลื่อนที่ ขี่ และขนส่งสิ่งของได้
class Skateboard implements CanMove, Rideable
{
   ...
}
ชั้นSkateboardเรียนสามารถเคลื่อนที่และขี่ได้


2. บทบาท

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

ประเด็นทั้งหมดคือคุณไม่จำเป็นต้องเขียนโค้ดสำหรับแต่ละคลาสเพื่อโต้ตอบกับคลาสอื่นๆ คุณเพียงแค่ต้องโต้ตอบกับบทบาทของพวกเขา (ส่วนต่อประสาน)

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

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

รหัส คำอธิบาย
interface CanSpeak
{
   void speak();
}
ความCanSpeakสามารถ อินเทอร์เฟซนี้เข้าใจคำสั่งถึงspeakซึ่งหมายความว่ามีวิธีการที่สอดคล้องกัน
class Cat implements CanSpeak
{
   void speak()
   {
      println("MEOW");
   }
}

class Dog implements CanSpeak
{
   void speak()
   {
      println("WOOF");
   }
}

class Fish
{
   ...
}
สัตว์ที่มีคุณสมบัตินี้

เพื่ออำนวยความสะดวกในการทำความเข้าใจ เราได้ระบุชื่อชั้นเรียนเป็นภาษาอังกฤษ สิ่งนี้ได้รับอนุญาตใน Java แต่เป็นสิ่งที่ไม่พึงปรารถนาอย่างยิ่ง













ของเราFishไม่มีความสามารถในการพูด (ไม่ได้ใช้CanSpeakอินเทอร์เฟซ)

public static void main(String[] args)
{
   // Add all the animals to the list
   ArrayList pets = new ArrayList();
   pets.add(new Cat());
   pets.add(new Dog());
   pets.add(new Fish());

   // If the ability exists, then make a sound
   for(Object pet: pets)
   {
      if (pet instanceof CanSpeak)
      {
         CanSpeak loudmouth = (CanSpeak) pet;
         loudmouth.speak();
      }
   }
}
แล้วเราจะให้คำสั่งแก่พวกเขาอย่างไร?

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

และเมื่อรวมกับความหลากหลาย แนวทางนี้มักจะประสบความสำเร็จอย่างยอดเยี่ยม



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()เมธอด