อะไรคือความแตกต่างระหว่างคลาสนามธรรมอินเตอร์เฟสและเวลาที่จะใช้


15

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

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

นี่คือสองคลาสที่ฉันสร้าง:

class Ad {
    $title;
    $description
    $price;

    function get_data($website){  }

    function validate_price(){  }
 }


class calendar_event {
    $title;
    $description

    $start_date;

    function get_data($website){ //guts }

    function validate_dates(){ //guts }
 }

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

ตอนนี้ฉันได้ละเมิดหลักการของDRYและฉันกำลังจัดการและเปลี่ยนรหัสเดียวกันในหลาย ๆ ไฟล์ ฉันตั้งใจจะมีคลาสมากขึ้นเช่นเรือม้าหรืออะไรก็ตาม

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

abstract class content {
    $title;
    $description


    function get_data($website){  }

    function common_function2() { }
    function common_function3() { }
 }


class calendar_event extends content {

    $start_date;

    function validate_dates(){  }
 }

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

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

ขอบคุณ!


มีตัวอย่างที่ดีมากมายทางออนไลน์ ฉันคิดว่านี่เป็นหนึ่งในนั้น javapapers.com/core-java/abstract-and-interface-core-java-2/…
Siva

คำตอบ:


26

ในแง่ของคนธรรมดา:

อินเทอร์เฟซสำหรับ"สามารถทำ / สามารถถือว่าเป็น"ประเภทของความสัมพันธ์

คลาสนามธรรม (รวมถึงรูปธรรม)มีไว้สำหรับความสัมพันธ์แบบ"เป็น"

ดูตัวอย่างเหล่านี้:

class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;

Bird, MosquitoและมีHorse Animalsพวกเขาเกี่ยวข้องกัน eat(), metabolize() and reproduce()พวกเขาได้รับมรดกวิธีการที่พบจากสัตว์เช่น บางทีพวกเขาจะแทนที่วิธีการเหล่านี้โดยเพิ่มเป็นพิเศษเล็กน้อยสำหรับพวกเขา แต่พวกเขาใช้ประโยชน์จากพฤติกรรมเริ่มต้นที่นำมาใช้ในสัตว์เช่นmetabolizeGlucose().

Planeไม่เกี่ยวข้องกับBird, หรือMosquitoHorse

Flightจะดำเนินการโดยการที่แตกต่างกันในชั้นเรียนที่ไม่เกี่ยวข้องเช่นและBirdPlane

AccountableAssetนอกจากนี้ยังมีการใช้งานที่แตกต่างกันโดยการเรียนที่ไม่เกี่ยวข้องเช่นและPlaneRaceHorse

Horse ไม่ใช้เที่ยวบิน

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

ในทางกลับกันอินเทอร์เฟซไม่สร้างลำดับชั้น แต่พวกเขาสามารถช่วยทำให้พฤติกรรมบางอย่างสอดคล้องกันข้ามลำดับชั้นเพื่อให้คุณสามารถแยกพวกมันออกจากลำดับชั้นในบริบทบางอย่าง

ตัวอย่างเช่นคุณสามารถมีโปรแกรมรวมมูลค่าของกลุ่มที่AccountableAssetsไม่คำนึงถึงความเป็นอยู่ของพวกเขาหรือRaceHorsesPlanes


น่าอัศจรรย์ ส่วนต่อประสานมีฟังก์ชั่นบางอย่างซึ่งกำหนดcan do/can be treated asว่าคลาสนามธรรมทำหน้าที่เป็นพื้นฐาน!
Abhiroj Panwar

13

คุณสามารถอนุมานคำตอบได้อย่างมีเหตุมีผลเนื่องจากคุณทราบถึงความแตกต่างระหว่างทั้งสอง

อินเทอร์เฟซกำหนดสัญญาทั่วไป เช่นอินเทอร์เฟซที่เรียกว่า IAnimal ที่สัตว์ทุกตัวใช้ฟังก์ชั่นร่วมกันเช่น Eat (), Move (), Attack () เป็นต้นในขณะที่พวกเขาทั้งหมดแบ่งปันฟังก์ชั่นเดียวกันทั้งหมดหรือส่วนใหญ่มีวิธีที่แตกต่างกัน มัน.

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

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

นอกจากนี้ดูเหมือนว่าจะไม่มีปัญหาการขาดแคลนผลลัพธ์ใน Google


3

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

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

หวังว่าจะช่วยได้ แต่มีข้อมูลมากมายเกี่ยวกับออนไลน์นี้ Leo


2
Classes cannot have multiple inheritance- จริงสำหรับภาษาอย่าง Java และ C # ไม่ใช่จริงสำหรับ C ++
Robert Harvey

3

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

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

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

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


3

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

ถ้าคุณต้องการให้ความสำคัญกับพฤติกรรมการใช้ซ้ำและ polymorphic ให้เลือกคลาสนามธรรม ตัวอย่างเช่นพนักงานประเภทต่างๆมีข้อกำหนดแตกต่างกัน แต่ทุกคนได้รับบางอย่างที่เหมือนกัน ดังนั้นคลาสนามธรรมเหมาะที่จะใช้แทนเพราะ commonalities สามารถแสดงในคลาสนามธรรมพื้นฐานEmployeeและความแตกต่างสามารถนำไปใช้ในคลาสที่ได้รับเช่นManagerหรือWorkerอื่น ๆ

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


-3
  1. ความแตกต่างที่สำคัญคือวิธีการของส่วนต่อประสาน Java เป็นนามธรรมโดยปริยายและไม่สามารถใช้งานได้ คลาสนามธรรมของ Java สามารถมีวิธีการอินสแตนซ์ที่ใช้พฤติกรรมเริ่มต้น
  2. ตัวแปรที่ประกาศในอินเตอร์เฟส Java นั้นเป็นค่าเริ่มต้นสุดท้าย คลาสนามธรรมอาจมีตัวแปรที่ไม่สิ้นสุด
  3. สมาชิกของส่วนต่อประสาน Java เป็นสาธารณะโดยค่าเริ่มต้น คลาสนามธรรมของ Java สามารถมีสมาชิกคลาสได้ตามปกติเช่นส่วนตัวมีการป้องกัน ฯลฯ
  4. ส่วนต่อประสาน Java ควรจะดำเนินการโดยใช้คำหลัก“ ดำเนินการ”; คลาสนามธรรมของ Java ควรถูกขยายโดยใช้คีย์เวิร์ด“ extends”
  5. อินเทอร์เฟซสามารถขยายอินเทอร์เฟซ Java อื่นเท่านั้นคลาสนามธรรมสามารถขยายคลาส Java อื่นและใช้อินเทอร์เฟซ Java หลายอินเทอร์เฟซ
  6. คลาส Java สามารถใช้หลายอินเตอร์เฟส แต่สามารถขยายคลาสนามธรรมเพียงคลาสเดียวเท่านั้น
  7. อินเทอร์เฟซเป็นนามธรรมอย่างแน่นอนและไม่สามารถสร้างอินสแตนซ์ได้ คลาสนามธรรมของ Java ไม่สามารถสร้างอินสแตนซ์ได้ แต่สามารถเรียกใช้ได้ถ้ามี main () อยู่
  8. เมื่อเปรียบเทียบกับคลาส abstract ของจาวาอินเทอร์เฟซ java จะช้าเนื่องจากต้องใช้การเปลี่ยนทิศทางเพิ่มเติม
  9. อินเทอร์เฟซและคลาสนามธรรมใน Java คือคุณไม่สามารถสร้างวิธีที่ไม่เป็นนามธรรมในอินเทอร์เฟซทุกวิธีในอินเทอร์เฟซเป็นนามธรรมเริ่มต้น แต่คุณสามารถสร้างวิธีที่ไม่เป็นนามธรรมในคลาสนามธรรม
  10. คลาสนามธรรมกับอินเทอร์เฟซใน Java คืออินเตอร์เฟสเหมาะสำหรับการประกาศประเภทและคลาสนามธรรมเหมาะสำหรับการนำโค้ดกลับมาใช้ใหม่และมุมมองวิวัฒนาการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.