นี่อาจเป็นคำถาม OOP ทั่วไป ฉันต้องการทำการเปรียบเทียบทั่วไประหว่างอินเทอร์เฟซและคลาสนามธรรมบนพื้นฐานของการใช้งานของพวกเขา
เมื่อใดที่จะต้องการใช้อินเทอร์เฟซและเมื่อใดที่จะต้องการใช้คลาสนามธรรม ?
นี่อาจเป็นคำถาม OOP ทั่วไป ฉันต้องการทำการเปรียบเทียบทั่วไประหว่างอินเทอร์เฟซและคลาสนามธรรมบนพื้นฐานของการใช้งานของพวกเขา
เมื่อใดที่จะต้องการใช้อินเทอร์เฟซและเมื่อใดที่จะต้องการใช้คลาสนามธรรม ?
คำตอบ:
ฉันเขียนบทความเกี่ยวกับเรื่องนั้น:
สรุป:
เมื่อเราพูดถึงคลาสนามธรรมเราจะนิยามลักษณะของประเภทวัตถุ การระบุว่าวัตถุคืออะไร
เมื่อเราพูดถึงอินเทอร์เฟซและกำหนดความสามารถที่เราสัญญาว่าจะให้บริการเรากำลังพูดถึงการสร้างสัญญาเกี่ยวกับสิ่งที่วัตถุสามารถทำได้
Interfaces do not express something like "a Doberman is a type of dog and every dog can walk" but more like "this thing can walk"
มาก: ขอบคุณ
Use abstract classes and inheritance if you can make the statement “A is a B”. Use interfaces if you can make the statement “A is capable of [doing] as”
คลาสนามธรรมสามารถมีสถานะหรือการใช้งานร่วมกันได้ อินเทอร์เฟซเป็นเพียงสัญญาให้รัฐหรือฟังก์ชันการทำงาน คลาสนามธรรมที่ดีจะลดจำนวนของรหัสที่ต้องเขียนใหม่เนื่องจากการทำงานหรือสถานะของมันสามารถใช้ร่วมกันได้ อินเทอร์เฟซไม่มีข้อมูลที่กำหนดที่จะแบ่งปัน
โดยส่วนตัวฉันแทบจะไม่จำเป็นต้องเขียนคลาสนามธรรมเลย
บ่อยครั้งที่ฉันเห็นว่ามีการใช้คลาสนามธรรม (mis) เป็นเพราะผู้เขียนคลาสนามธรรมใช้รูปแบบ "วิธีการแบบ"
ปัญหาเกี่ยวกับ "วิธีการแบบ" คือมันเกือบทุกครั้งที่ผู้เข้ามาใหม่ - คลาส "ที่ได้รับ" ไม่เพียง แต่รู้วิธีการ "นามธรรม" ของคลาสพื้นฐานที่ใช้งาน แต่ยังเกี่ยวกับวิธีการสาธารณะของคลาสพื้นฐาน แม้ว่าเวลาส่วนใหญ่จะไม่จำเป็นต้องเรียกพวกเขา
ตัวอย่าง (เรียบง่ายเกินไป):
abstract class QuickSorter
{
public void Sort(object[] items)
{
// implementation code that somewhere along the way calls:
bool less = compare(x,y);
// ... more implementation code
}
abstract bool compare(object lhs, object rhs);
}
ดังนั้นที่นี่ผู้เขียนของคลาสนี้ได้เขียนอัลกอริทึมทั่วไปและตั้งใจสำหรับคนที่จะใช้มันโดย "เชี่ยวชาญ" โดยการให้ "hooks" ของตัวเอง - ในกรณีนี้วิธีการ "เปรียบเทียบ"
ดังนั้นการใช้งานที่ตั้งใจไว้เป็นดังนี้:
class NameSorter : QuickSorter
{
public bool compare(object lhs, object rhs)
{
// etc.
}
}
ปัญหาที่เกิดขึ้นคือคุณได้ผสมผสานแนวคิดทั้งสองอย่างเกินควร:
ในโค้ดข้างต้นตามหลักทฤษฏีผู้เขียนวิธีการ "เปรียบเทียบ" สามารถโทรกลับไปยังวิธีการ "เรียงลำดับ" superclass อีกครั้ง ... แม้ว่าในทางปฏิบัติพวกเขาจะไม่ต้องการหรือต้องการทำสิ่งนี้
ราคาที่คุณจ่ายสำหรับข้อต่อที่ไม่จำเป็นนี้คือมันยากที่จะเปลี่ยนซูเปอร์คลาสและในภาษา OO ส่วนใหญ่ไม่สามารถเปลี่ยนได้ในรันไทม์
วิธีทางเลือกคือใช้รูปแบบการออกแบบ "กลยุทธ์" แทน:
interface IComparator
{
bool compare(object lhs, object rhs);
}
class QuickSorter
{
private readonly IComparator comparator;
public QuickSorter(IComparator comparator)
{
this.comparator = comparator;
}
public void Sort(object[] items)
{
// usual code but call comparator.Compare();
}
}
class NameComparator : IComparator
{
bool compare(object lhs, object rhs)
{
// same code as before;
}
}
ดังนั้นขอให้สังเกตตอนนี้: ทั้งหมดที่เรามีคืออินเทอร์เฟซและการใช้งานอินเทอร์เฟซเหล่านั้นอย่างเป็นรูปธรรม ในทางปฏิบัติคุณไม่จำเป็นต้องมีอย่างอื่นในการออกแบบ OO ระดับสูง
ในการ "ซ่อน" ข้อเท็จจริงที่เราได้ใช้ "การเรียงลำดับชื่อ" โดยใช้คลาส "QuickSort" และ "NameComparator" เราอาจยังคงเขียนวิธีการจากโรงงานไว้:
ISorter CreateNameSorter()
{
return new QuickSorter(new NameComparator());
}
ใดคุณมีคลาสนามธรรมคุณสามารถทำเช่นนี้ ... แม้ว่าจะมีความสัมพันธ์แบบผู้เข้ามาใหม่ระหว่างฐานและคลาสที่ได้รับมาโดยธรรมชาติก็มักจะจ่ายให้ชัดเจน
หนึ่งความคิดสุดท้าย: สิ่งที่เราทำไปแล้วคือ "เขียน" ฟังก์ชั่น "NameSorting" โดยใช้ฟังก์ชั่น "QuickSort" และฟังก์ชั่น "NameComparison" ... ในภาษาโปรแกรมที่ใช้งานได้รูปแบบการเขียนโปรแกรมนี้ยิ่งเป็นธรรมชาติมากขึ้น ด้วยรหัสน้อย
หากคุณกำลังมองหาจาวาเป็นภาษา OOP
" อินเตอร์เฟสไม่ได้จัดเตรียมการใช้วิธีการ " ไม่สามารถใช้ได้กับการเปิดตัว Java 8 อีกต่อไป ตอนนี้จาวาให้การใช้งานในส่วนติดต่อสำหรับวิธีการเริ่มต้น
ในแง่ง่ายฉันต้องการที่จะใช้
อินเทอร์เฟซ:การใช้สัญญาโดยวัตถุที่ไม่เกี่ยวข้องหลายรายการ มันให้ความสามารถ " HAS A "
ระดับนามธรรม:เพื่อใช้พฤติกรรมที่เหมือนกันหรือแตกต่างระหว่างวัตถุที่เกี่ยวข้องหลายรายการ มันสร้างความสัมพันธ์" IS A "
เว็บไซต์ Oracle ให้ความแตกต่างที่สำคัญระหว่างinterface
และabstract
คลาส
ลองใช้คลาสนามธรรมหาก:
พิจารณาใช้อินเตอร์เฟสหาก:
Serializable
อินเตอร์เฟซตัวอย่าง:
ระดับนามธรรม ( เป็นความสัมพันธ์)
Readerเป็นคลาสนามธรรม
BufferedReaderเป็นReader
FileReaderเป็นReader
FileReader
และBufferedReader
ใช้เพื่อจุดประสงค์ทั่วไป: การอ่านข้อมูลและเกี่ยวข้องกันReader
ชั้นเรียน
อินเตอร์เฟส ( ความสามารถHAS A )
Serializableเป็นอินเตอร์เฟส
สมมติว่าคุณมีสองคลาสในแอปพลิเคชันซึ่งกำลังใช้งานSerializable
อินเทอร์เฟซ
Employee implements Serializable
Game implements Serializable
ที่นี่คุณไม่สามารถสร้างความสัมพันธ์ผ่านSerializable
อินเทอร์เฟซระหว่างEmployee
และGame
ซึ่งมีวัตถุประสงค์เพื่อวัตถุประสงค์ที่แตกต่างกัน ทั้งสองมีความสามารถในการทำให้เป็นอันดับรัฐและการเปรียบเทียบสิ้นสุดลงที่นั่น
ดูที่โพสต์เหล่านี้:
ฉันจะอธิบายความแตกต่างระหว่างอินเทอร์เฟซกับคลาสนามธรรมได้อย่างไร
ตกลงมีเพียง "grokked" ตัวเอง - นี่มันอยู่ในเงื่อนไขของคนธรรมดา (รู้สึกอิสระที่จะแก้ไขฉันถ้าฉันผิด) - ฉันรู้ว่าหัวข้อนี้เป็น oooooold แต่คนอื่นอาจสะดุดในวันหนึ่ง ...
คลาสนามธรรมช่วยให้คุณสร้างพิมพ์เขียวและอนุญาตให้คุณสร้างคุณสมบัติและวิธีการ CONSTRUCT (implement) เพิ่มเติมที่คุณต้องการให้ลูกหลานทั้งหมดของมันครอบครอง
อินเทอร์เฟซในอีกทางหนึ่งช่วยให้คุณสามารถประกาศว่าคุณต้องการคุณสมบัติและ / หรือวิธีการที่มีชื่อที่กำหนดให้มีอยู่ในทุกชั้นที่ใช้มัน - แต่ไม่ได้ระบุวิธีที่คุณควรใช้มัน นอกจากนี้คลาสสามารถใช้อินเตอร์เฟส MANY ได้ แต่สามารถขยายคลาส Abstract ได้เพียงคลาสเดียวเท่านั้น อินเทอร์เฟซเป็นเครื่องมือสถาปัตยกรรมระดับสูงมากกว่า (ซึ่งจะชัดเจนขึ้นหากคุณเริ่มเข้าใจรูปแบบการออกแบบ) - บทคัดย่อมีเท้าในค่ายทั้งสองและสามารถทำงานสกปรกบางอย่างได้เช่นกัน
เหตุใดจึงต้องใช้อีกอันหนึ่ง อดีตช่วยให้มากขึ้นเป็นรูปธรรมนิยามของลูกหลาน - หลังช่วยให้มากขึ้นหลายรูปแบบ จุดสุดท้ายนี้มีความสำคัญต่อผู้ใช้ / ผู้เข้ารหัสซึ่งสามารถใช้ข้อมูลนี้เพื่อใช้ AP I (nterface)ในชุดค่าผสม / รูปร่างที่หลากหลายเพื่อให้เหมาะกับความต้องการของพวกเขา
ฉันคิดว่านี่เป็นช่วงเวลาที่ "หลอดไฟ" สำหรับฉัน - คิดถึงอินเทอร์เฟซน้อยกว่าจากมุมมองของผู้เขียนและอีกมากจาก coder ใด ๆ ที่จะมาในภายหลังในห่วงโซ่ที่เพิ่มการใช้งานโครงการหรือขยาย API
สองเซ็นต์ของฉัน:
อินเทอร์เฟซโดยทั่วไปกำหนดสัญญาว่าคลาสใด ๆ ที่ใช้งานต้องปฏิบัติตาม (ใช้สมาชิกอินเทอร์เฟซ) ไม่มีรหัสใด ๆ
ในทางตรงกันข้ามคลาสนามธรรมสามารถมีรหัสและอาจมีวิธีการทำเครื่องหมายเป็นนามธรรมซึ่งคลาสสืบทอดจะต้องดำเนินการ
สถานการณ์ที่ไม่ค่อยเกิดขึ้นที่ฉันใช้คลาสนามธรรมคือเมื่อฉันมีฟังก์ชั่นเริ่มต้นบางอย่างที่คลาสสืบทอดอาจไม่น่าสนใจในการเอาชนะกล่าวคลาสฐานนามธรรมที่คลาสเฉพาะบางคลาสสืบทอดมา
ตัวอย่าง (เป็นพื้นฐานมาก!): พิจารณาชั้นฐานที่เรียกว่าลูกค้าซึ่งมีวิธีการที่เป็นนามธรรมเช่นCalculatePayment()
, CalculateRewardPoints()
และบางส่วนวิธีการที่ไม่ใช่นามธรรมเช่น,GetName()
SavePaymentDetails()
คลาสพิเศษที่ชอบRegularCustomer
และGoldCustomer
จะสืบทอดจากCustomer
คลาสฐานและใช้ตรรกะCalculatePayment()
และCalculateRewardPoints()
เมธอดของตนเองแต่จะใช้GetName()
และSavePaymentDetails()
วิธีการใหม่
คุณสามารถเพิ่มฟังก์ชันการทำงานเพิ่มเติมให้กับคลาสนามธรรม (ไม่ใช่วิธีที่เป็นนามธรรม) โดยไม่มีผลกับคลาสย่อยที่ใช้เวอร์ชันเก่ากว่า ขณะที่การเพิ่มเมธอดให้กับอินเตอร์เฟสจะมีผลกับคลาสทั้งหมดที่นำไปใช้งานเนื่องจากพวกเขาต้องการใช้สมาชิกอินเทอร์เฟซที่เพิ่งเพิ่มเข้าไปใหม่
คลาสนามธรรมกับสมาชิกนามธรรมทั้งหมดจะคล้ายกับอินเทอร์เฟซ
เมื่อใดที่ต้องทำสิ่งที่ง่ายมากถ้าคุณมีแนวคิดที่ชัดเจนในใจของคุณ
คลาสนามธรรมสามารถรับมาได้ในขณะที่อินเทอร์เฟซสามารถใช้งานได้ มีความแตกต่างระหว่างคนทั้งสอง เมื่อคุณได้รับคลาส Abstract ความสัมพันธ์ระหว่างคลาสที่ได้รับและคลาสพื้นฐานคือความสัมพันธ์ 'คือ' เช่นสุนัขเป็นสัตว์แกะเป็นสัตว์ซึ่งหมายความว่าคลาสที่ได้รับจะสืบทอดคุณสมบัติบางอย่างจากคลาสฐาน
ในขณะที่การนำอินเตอร์เฟสไปใช้งานความสัมพันธ์คือ "สามารถ" เช่นสุนัขสามารถเป็นสุนัขสายลับ สุนัขสามารถเป็นสุนัขในคณะละครสัตว์ได้ สุนัขสามารถเป็นสุนัขแข่งได้ ซึ่งหมายความว่าคุณใช้วิธีการบางอย่างเพื่อรับบางสิ่งบางอย่าง
ฉันหวังว่าฉันชัดเจน
1. หากคุณกำลังสร้างบางสิ่งบางอย่างที่มีฟังก์ชั่นการใช้งานทั่วไปสำหรับคลาสที่ไม่เกี่ยวข้องให้ใช้อินเทอร์เฟซ
2. ถ้าคุณกำลังสร้างบางสิ่งบางอย่างสำหรับวัตถุที่เกี่ยวข้องอย่างใกล้ชิดในลำดับชั้นใช้คลาสนามธรรม
ฉันเขียนบทความว่าจะใช้คลาสนามธรรมเมื่อใดและใช้อินเทอร์เฟซเมื่อใด มีความแตกต่างระหว่างพวกเขามากกว่า "one IS-A ... หนึ่ง CAN-DO ... " สำหรับฉันแล้วคำตอบเหล่านั้นเป็นกระป๋อง ฉันพูดถึงเหตุผลสองสามข้อเมื่อใช้อย่างใดอย่างหนึ่ง หวังว่ามันจะช่วย
ฉันคิดว่าวิธีที่กระชับที่สุดของการวางไว้คือ:
คุณสมบัติที่ใช้ร่วมกัน => คลาสนามธรรม
ฟังก์ชั่นที่ใช้ร่วมกัน => ส่วนต่อประสาน
และทำให้มันกระชับน้อยลง ...
ตัวอย่างคลาสนามธรรม:
public abstract class BaseAnimal
{
public int NumberOfLegs { get; set; }
protected BaseAnimal(int numberOfLegs)
{
NumberOfLegs = numberOfLegs;
}
}
public class Dog : BaseAnimal
{
public Dog() : base(4) { }
}
public class Human : BaseAnimal
{
public Human() : base(2) { }
}
เนื่องจากสัตว์มีคุณสมบัติที่ใช้ร่วมกัน - จำนวนขาในกรณีนี้ - มันเหมาะสมที่จะทำให้คลาสนามธรรมที่มีคุณสมบัติที่ใช้ร่วมกันนี้ นอกจากนี้ยังช่วยให้เราสามารถเขียนรหัสทั่วไปที่ทำงานในคุณสมบัตินั้น ตัวอย่างเช่น:
public static int CountAllLegs(List<BaseAnimal> animals)
{
int legCount = 0;
foreach (BaseAnimal animal in animals)
{
legCount += animal.NumberOfLegs;
}
return legCount;
}
ตัวอย่างการเชื่อมต่อ:
public interface IMakeSound
{
void MakeSound();
}
public class Car : IMakeSound
{
public void MakeSound() => Console.WriteLine("Vroom!");
}
public class Vuvuzela : IMakeSound
{
public void MakeSound() => Console.WriteLine("VZZZZZZZZZZZZZ!");
}
โปรดทราบว่า Vuvuzelas และ Cars เป็นสิ่งที่แตกต่างกันโดยสิ้นเชิง แต่มีฟังก์ชั่นการใช้งานร่วมกัน: สร้างเสียง ดังนั้นอินเทอร์เฟซที่เหมาะสม นอกจากนี้ยังอนุญาตให้โปรแกรมเมอร์จัดกลุ่มสิ่งต่าง ๆ ที่ทำให้เกิดเสียงร่วมกันภายใต้อินเทอร์เฟซทั่วไป - IMakeSound
ในกรณีนี้ ด้วยการออกแบบนี้คุณสามารถเขียนรหัสต่อไปนี้:
List<IMakeSound> soundMakers = new List<ImakeSound>();
soundMakers.Add(new Car());
soundMakers.Add(new Vuvuzela());
soundMakers.Add(new Car());
soundMakers.Add(new Vuvuzela());
soundMakers.Add(new Vuvuzela());
foreach (IMakeSound soundMaker in soundMakers)
{
soundMaker.MakeSound();
}
คุณสามารถบอกได้ว่าจะเอาท์พุทอะไร?
สุดท้ายคุณสามารถรวมสองสิ่งนี้เข้าด้วยกัน
ตัวอย่างรวม:
public interface IMakeSound
{
void MakeSound();
}
public abstract class BaseAnimal : IMakeSound
{
public int NumberOfLegs { get; set; }
protected BaseAnimal(int numberOfLegs)
{
NumberOfLegs = numberOfLegs;
}
public abstract void MakeSound();
}
public class Cat : BaseAnimal
{
public Cat() : base(4) { }
public override void MakeSound() => Console.WriteLine("Meow!");
}
public class Human : BaseAnimal
{
public Human() : base(2) { }
public override void MakeSound() => Console.WriteLine("Hello, world!");
}
ที่นี่เราต้องการให้ทุกBaseAnimal
คนส่งเสียง แต่เรายังไม่รู้การใช้งาน ในกรณีเช่นนี้เราสามารถสรุปการใช้อินเตอร์เฟสและมอบการใช้งานให้กับคลาสย่อย
สุดท้ายจุดหนึ่งจำได้อย่างไรในตัวอย่างคลาสนามธรรมเราสามารถทำงานกับคุณสมบัติที่ใช้ร่วมกันของวัตถุที่แตกต่างกันและในตัวอย่างอินเตอร์เฟสเราสามารถเรียกใช้ฟังก์ชั่นที่ใช้ร่วมกันของวัตถุที่แตกต่างกันได้อย่างไร ในตัวอย่างสุดท้ายนี้เราทำได้ทั้งสองอย่าง
เมื่อใดที่ต้องการคลาสนามธรรมผ่านอินเตอร์เฟส?
เมื่อใดที่ต้องการอินเตอร์เฟซมากกว่าคลาสนามธรรม?
คลาสอาจสืบทอดมาจากคลาสฐานเดียวเท่านั้นดังนั้นหากคุณต้องการใช้คลาสนามธรรมเพื่อจัดเตรียมพหุสัณฐานให้กับกลุ่มของคลาสคลาสเหล่านั้นทั้งหมดจะต้องสืบทอดจากคลาสนั้น คลาสที่เป็นนามธรรมอาจจัดเตรียมสมาชิกที่ถูกนำไปใช้แล้ว ดังนั้นคุณสามารถมั่นใจได้ว่ามีฟังก์ชั่นที่เหมือนกันในระดับนามธรรม แต่ไม่สามารถใช้อินเทอร์เฟซได้
นี่คือคำแนะนำบางส่วนเพื่อช่วยคุณตัดสินใจว่าจะใช้ส่วนต่อประสานหรือคลาสนามธรรมเพื่อจัดเตรียมความหลากหลายให้กับองค์ประกอบของคุณ
คัดลอกมาจาก:
http://msdn.microsoft.com/en-us/library/scsyfw1d%28v=vs.71%29.aspx
ลองใช้คลาสนามธรรมถ้าข้อความใด ๆ เหล่านี้ตรงกับสถานการณ์ของคุณ:
พิจารณาการใช้อินเทอร์เฟซหากข้อความใด ๆ เหล่านี้นำไปใช้กับสถานการณ์ของคุณ:
คำตอบนั้นแตกต่างกันไปในแต่ละภาษา ตัวอย่างเช่นใน Java คลาสสามารถใช้ (สืบทอดจาก) หลายอินเตอร์เฟส แต่สืบทอดจากคลาสนามธรรมเพียงคลาสเดียวเท่านั้น ดังนั้นอินเตอร์เฟสจึงให้ความยืดหยุ่นมากกว่า แต่นี่ไม่เป็นความจริงใน C ++
สำหรับฉันฉันจะไปกับอินเตอร์เฟสในหลายกรณี แต่ฉันชอบคลาสนามธรรมในบางกรณี
คลาสใน OO generaly หมายถึงการใช้งาน ฉันใช้คลาสนามธรรมเมื่อฉันต้องการบังคับรายละเอียดการใช้งานบางอย่างให้กับเด็กที่ฉันไปด้วยอินเตอร์เฟส
แน่นอนคลาสนามธรรมมีประโยชน์ไม่เพียง แต่ในการบังคับใช้ แต่ยังใช้ในการแบ่งปันรายละเอียดเฉพาะบางอย่างในคลาสที่เกี่ยวข้องมากมาย
ใช้คลาสนามธรรมหากคุณต้องการให้มีการใช้งานพื้นฐานบางอย่าง
ในจาวาคุณสามารถสืบทอดจากคลาสหนึ่ง (นามธรรม) เพื่อ "ให้" ฟังก์ชั่นและคุณสามารถใช้อินเทอร์เฟซมากมายเพื่อ "ฟังก์ชั่น" มั่นใจ
หมดจดบนพื้นฐานของมรดกคุณจะใช้บทคัดย่อที่คุณกำหนดได้อย่างชัดเจนลูกหลาน, ความสัมพันธ์ที่เป็นนามธรรม (เช่นสัตว์> แมว) และ / หรือจำเป็นต้องมีการถ่ายทอดทางพันธุกรรมของคุณสมบัติเสมือนหรือไม่ใช่แบบสาธารณะรัฐที่ใช้ร่วมกันโดยเฉพาะอย่างยิ่ง (ซึ่งเชื่อมต่อไม่สามารถสนับสนุน )
คุณควรลองและสนับสนุนการจัดองค์ประกอบ (ผ่านการฉีดขึ้นต่อกัน) ผ่านการสืบทอดที่คุณสามารถทำได้และโปรดทราบว่าการเชื่อมต่อของสัญญาสนับสนุนการทดสอบหน่วยการแยกข้อกังวลและ (การแปรเปลี่ยนภาษา) หลายมรดกในลักษณะที่บทคัดย่อไม่สามารถ
สถานที่ที่น่าสนใจแห่งหนึ่งที่อินเตอร์เฟซดีกว่าคลาสนามธรรมคือเมื่อคุณต้องการเพิ่มฟังก์ชันการทำงานพิเศษให้กับกลุ่มของวัตถุ (ที่เกี่ยวข้องหรือไม่เกี่ยวข้อง) หากคุณไม่สามารถให้คลาสนามธรรมพื้นฐานแก่พวกเขา (เช่นพวกเขามีsealed
หรือมีพาเรนต์แล้ว) คุณสามารถให้อินเทอร์เฟซดัมมี (ว่าง) แทนพวกเขาได้และจากนั้นก็เขียนวิธีการขยายสำหรับอินเทอร์เฟซนั้น
นี่อาจเป็นการยากที่จะโทร ...
ตัวชี้หนึ่งที่ฉันสามารถให้: วัตถุสามารถใช้อินเทอร์เฟซจำนวนมากในขณะที่วัตถุสามารถสืบทอดคลาสฐานเดียวเท่านั้น (ในภาษา OO ที่ทันสมัยเช่น c # ฉันรู้ว่า C ++ มีหลายมรดก - แต่ไม่ขมวดคิ้ว?)
คลาสนามธรรมสามารถมีการนำไปใช้งานได้
อินเทอร์เฟซไม่มีการใช้งานมันเพียงกำหนดชนิดของสัญญา
อาจมีความแตกต่างขึ้นอยู่กับภาษาด้วยเช่นกันตัวอย่างเช่น C # ไม่มีการสืบทอดหลายอย่าง แต่หลายอินเตอร์เฟสสามารถนำไปใช้ในคลาสได้
กฎหัวแม่มือพื้นฐานคือ: สำหรับ"คำนาม" ให้ใช้คลาสนามธรรมและสำหรับอินเตอร์เฟซการใช้ "คำกริยา"
เช่น: car
เป็นคลาสนามธรรมและdrive
เราสามารถทำให้เป็นอินเทอร์เฟซ
drive
ในรถยนต์ - นั่นคือคลาสนามธรรม