ฉันจะรู้ได้อย่างไรว่าจะสร้างอินเทอร์เฟซเมื่อใด


196

ฉันอยู่ในช่วงของการเรียนรู้การพัฒนาที่ฉันรู้สึกว่าฉันต้องเรียนรู้เพิ่มเติมเกี่ยวกับอินเทอร์เฟซ

ฉันอ่านบ่อยเกี่ยวกับพวกเขา แต่ดูเหมือนว่าฉันไม่สามารถเข้าใจพวกเขาได้

ฉันได้อ่านตัวอย่างเช่น: คลาสสัตว์พื้นฐานพร้อมอินเทอร์เฟซ IAnimal สำหรับสิ่งต่าง ๆ เช่น 'Walk', 'Run', 'GetLegs' ฯลฯ - แต่ฉันไม่เคยทำงานอะไรมาแล้วรู้สึกเหมือน "เฮ้ฉันควรใช้อินเทอร์เฟซ นี่!"

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


1
คุณต้องตรวจสอบstackoverflow.com/q/8531292/1055241
gprathour

คำตอบ:


151

มันแก้ปัญหาที่เป็นรูปธรรมนี้:

คุณมี a, b, c, d จาก 4 ชนิดที่แตกต่างกัน ทั่วรหัสของคุณคุณมีสิ่งที่ชอบ:

a.Process();
b.Process();
c.Process();
d.Process();

ทำไมพวกเขาไม่ใช้ IProcessable แล้วทำ

List<IProcessable> list;

foreach(IProcessable p in list)
    p.Process();

สิ่งนี้จะขยายขนาดได้ดีขึ้นมากเมื่อคุณเพิ่มพูดคลาส 50 ประเภทที่ทำในสิ่งเดียวกัน


ปัญหาคอนกรีตอีกประการหนึ่ง:

คุณเคยดูที่ System.Linq.Enumerable หรือไม่? มันกำหนดวิธีการขยายจำนวนมากที่ทำงานกับประเภทใดก็ได้ที่ใช้ IEnumerable เนื่องจากสิ่งใดก็ตามที่ใช้ IEnumerable โดยทั่วไปจะพูดว่า "ฉันรองรับการวนซ้ำในรูปแบบ foreach-type unordered" คุณสามารถกำหนดพฤติกรรมที่ซับซ้อนได้ (Count, Max, Where, Select, ฯลฯ ) สำหรับประเภทที่นับได้


2
นั่นช่วยได้ อะไรคือข้อได้เปรียบของการมีส่วนต่อประสานที่มีอยู่แทนที่จะมีประเภทที่ทุกคนมีการใช้งานสำหรับกระบวนการ () วิธีการ?
user53885

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

คุณไม่จำเป็นต้องร่ายเมื่อเทียบกับ 50 คลาสที่ต่างกันด้วยวิธีการดำเนินการ C # ไม่ได้ใช้ "การพิมพ์เป็ด" ดังนั้นเพียงเพราะ A มีกระบวนการ () และ B มีกระบวนการ () ไม่ได้หมายความว่าไม่มีวิธีการทั่วไปในการโทรเช่นกัน คุณต้องการอินเทอร์เฟซสำหรับสิ่งนั้น
user7116

ขวา. ฉันเพิ่งเปลี่ยน "var" เป็น "IProcessable" เพื่อให้ตัวอย่างเหมาะสมยิ่งขึ้น
Jimmy

2
@Rogerio: ฉันพยายามที่จะเป็นทั่วไป ประเด็นก็คือไม่ใช่ "เมื่อคุณมีสิ่งที่มีฟังก์ชั่น Process ()" มัน "เมื่อคุณมีสิ่งต่าง ๆ ที่ใช้ชุดวิธีร่วมกัน" ตัวอย่างสามารถเปลี่ยนได้อย่างง่ายดายforeach(IMyCompanyWidgetFrobber a in list) a.Frob(widget, context);
Jimmy

133

ฉันชอบคำตอบของจิมมี่มาก แต่ฉันรู้สึกว่าฉันต้องเพิ่มบางสิ่งลงไป กุญแจสำคัญในการสิ่งที่ทั้งเป็น "สามารถ" ใน IProcess สามารถ. มันบ่งบอกถึงความสามารถ (หรือคุณสมบัติ แต่หมายถึง "คุณภาพที่แท้จริง" ไม่ใช่ในแง่ของคุณสมบัติ C #) ของวัตถุที่ใช้อินเทอร์เฟซ IAnimal อาจไม่ใช่ตัวอย่างที่ดีสำหรับอินเทอร์เฟซ แต่ IWalkable อาจเป็นอินเทอร์เฟซที่ดีถ้าระบบของคุณมีหลายสิ่งที่สามารถเดินได้ คุณอาจมีคลาสที่ได้มาจากสัตว์เช่นสุนัข, วัว, ปลา, งู สองคนแรกอาจใช้ IWalkable สองคนหลังไม่เดินดังนั้นพวกเขาก็จะไม่ ตอนนี้คุณถามว่า "ทำไมไม่เพียงแค่มีซุปเปอร์คลาสอีกประเภทหนึ่งคือ WalkingAnimal สุนัขและวัวตัวนั้นมาจากไหน" คำตอบคือเมื่อคุณมีบางสิ่งบางอย่างอยู่นอกต้นไม้มรดกที่สามารถเดินได้เช่นหุ่นยนต์ หุ่นยนต์จะใช้ IWalkable แต่อาจไม่ได้มาจากสัตว์ หากคุณต้องการรายการสิ่งที่สามารถเดินได้

ตอนนี้แทนที่ IWalkable ด้วยซอฟต์แวร์ที่มากกว่าเช่น IPersistable และการเปรียบเทียบจะใกล้เคียงกับสิ่งที่คุณเห็นในโปรแกรมจริงมากขึ้น


9
ฉันชอบสิ่งที่คุณเกิดขึ้น - "มันบ่งบอกถึงความสามารถ" อินเทอร์เฟซจำเป็นจริงๆเมื่อคุณจำเป็นต้องกำหนดความสามารถในการทำให้เกิด 'ความรู้เบื้องต้นต้องติดกับคลาส "ฐาน"
Ramiz Uddin

72

ใช้อินเตอร์เฟสเมื่อการใช้งานของฟังก์ชั่นเดียวกันจะแตกต่างกัน

ใช้คลาส abstract / base เมื่อคุณต้องการแชร์การใช้งานที่เป็นรูปธรรมทั่วไป


8
อันแรกเรียกว่า polymorphism ประการที่สองคืองูน้ำมัน - เว้นแต่ sublcass เป็น baseclass (ไม่มีการละเมิดหลักการทดแทน Liskov) คุณควรสนับสนุนการแต่งเพลงมากกว่าการสืบทอด
Arnis Lapsa

@ArnisLapsa ฉันไม่เข้าใจสิ่งที่คุณหมายถึงโดย "เว้นแต่ sublcass เป็น baseclass" เมื่อใด subclass จะไม่ "เป็น" baseclass? (ดังในisคำหลัก)
Marc.2377

32

คิดถึงอินเทอร์เฟซเช่นสัญญา เป็นวิธีที่จะพูดว่า "คลาสเหล่านี้ควรเป็นไปตามกฎชุดนี้"

ดังนั้นในตัวอย่าง IAnimal เป็นวิธีที่จะพูดว่า "ฉันต้องสามารถเรียกใช้ Run, Walk และอื่น ๆ ในคลาสที่ใช้ IAnimal"

ทำไมถึงมีประโยชน์ คุณอาจต้องการสร้างฟังก์ชั่นที่ต้องอาศัยความจริงที่ว่าคุณต้องสามารถเรียกใช้ Run and Walk ตัวอย่างเช่นบนวัตถุ คุณสามารถมีดังต่อไปนี้:

public void RunThenWalk(Monkey m) {
    m.Run();
    m.Walk();
}

public void RunThenWalk(Dog d) {
    d.Run();
    d.Walk();
}

... และทำซ้ำสำหรับวัตถุทั้งหมดที่คุณรู้ว่าสามารถวิ่งและเดินได้ อย่างไรก็ตามด้วยอินเทอร์เฟซ IAnimal ของคุณคุณสามารถกำหนดฟังก์ชันได้หนึ่งครั้งดังนี้:

public void RunThenWalk(IAnimal a) {
    a.Run();
    a.Walk();
}

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

นอกจากนี้ยังมีการอภิปรายที่ดีในคำถามที่เกี่ยวข้องนี้


1
อย่าลืมเกี่ยวกับความเป็นอิสระในการใช้งาน อินเทอร์เฟซอนุญาตให้หนึ่งไม่สนใจว่าจะใช้งานฟังก์ชันพื้นฐานเพียงใดซึ่งมันทำในสิ่งที่อินเตอร์เฟสบอกว่าทำ
Matthew Brubaker

18

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

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

if(myObject is Boat)
    ((Boat)myObject).Drive()
else
    if (myObject is Car)
        ((Car)myObject).Drive()

มันจะง่ายกว่ามากในการเขียน:

((IDrivable)myObject).Drive()

16

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

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


15

ฉันชอบการเปรียบเทียบของกองทัพ

จ่าไม่ดูแลถ้าคุณเป็นนักพัฒนาซอฟแวร์ , นักดนตรีหรือทนายความ
คุณจะถือว่าเป็นทหาร

UML

มันง่ายสำหรับจ่าที่จะไม่ใส่ใจกับรายละเอียดเฉพาะของบุคคลที่เขาทำงานด้วย
ปฏิบัติต่อทุกคนในฐานะทหารนามธรรม (... และลงโทษพวกเขาเมื่อพวกเขาล้มเหลวที่จะทำตัวเหมือนคน)

ความสามารถในการทำตัวเหมือนทหารเรียกว่า polymorphism

การเชื่อมต่อคือการสร้างซอฟต์แวร์ที่ช่วยให้เกิดความหลากหลาย

ต้องการรายละเอียดที่เป็นนามธรรมเพื่อให้ได้ความเรียบง่ายคือคำตอบสำหรับคำถามของคุณ

ความหลากหลายซึ่ง etymologically หมายถึง "หลายรูปแบบ" คือความสามารถในการรักษาวัตถุของคลาสย่อยใด ๆ ของคลาสฐานราวกับว่ามันเป็นวัตถุของคลาสฐาน ดังนั้นคลาสพื้นฐานจึงมีหลายรูปแบบ: คลาสพื้นฐานนั้นและคลาสย่อยใด ๆ

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


14

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

มีเหตุผลอื่นอีกมากมายที่ฉันได้พบเพื่อเสริมสร้างแนวปฏิบัติที่ดีในการปรับเปลี่ยนอินเทอร์เฟซ แต่การทดสอบหน่วย / การเยาะเย้ยคือสิ่งที่ให้ประสบการณ์ "ภาคปฏิบัติ" ในช่วงเวลาจริง

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


สิ่งที่ถูกต้องด้วยเหตุผลที่ผิด ในกรณีของคุณ - คุณจบลงด้วยการที่เรียกว่า "ส่วนต่อประสานส่วนหัว" และเพิ่มความซับซ้อนที่เกินน้ำหนักทำให้เกิดความเรียบง่าย
Arnis Lapsa

@Annis - การทดสอบหน่วยเป็น "เหตุผลที่ผิด" การเยาะเย้ยชั้นเรียนได้อย่างง่ายดายเพื่อลบการอ้างอิงในการทดสอบคือ "เหตุผลที่ผิด" ขออภัยฉันไม่เห็นด้วย
tvanfosson

1
การทดสอบควรมีผลต่อการออกแบบโดยอ้อมโดยให้ข้อเสนอแนะหากรหัสเป็นหรือไม่สามารถทดสอบได้ การเพิ่มคะแนนความสามารถในการขยายตัวเพื่อปรับปรุงความสามารถในการทดสอบนั้นเป็นเหมือนการโกง ฉันคิดว่า Mark Seeman ให้ผลรวมที่ดีที่สุดbit.ly/esi8Wp
Arnis Lapsa

1
@Annis - คุณใช้ mocks เลยในการทดสอบหน่วยของคุณหรือไม่? ถ้าไม่คุณจะลบการพึ่งพาการพึ่งพาได้อย่างไร คุณใช้ DI หรือเปล่า? การทดสอบหน่วยทำให้ฉันต้องใช้การเยาะเย้ยและ DI; การเยาะเย้ยและ DI ได้พิสูจน์คุณค่าของแนวปฏิบัติที่ดีในการใช้ส่วนต่อประสานเพื่อกำหนดสัญญาในลักษณะที่ไม่สามารถทำความเข้าใจด้านวิชาการได้ เนื่องจากการยอมรับ TDD ของฉันรหัสของฉันเป็นคู่น้อยกว่ามันจะเป็นอย่างอื่น ฉันคิดว่านั่นเป็นสิ่งที่ดี
tvanfosson

เพียงแค่บอกว่าการสลายตัวที่ไม่เป็นไปตามที่เรียกกันว่าข้อต่อตามธรรมชาตินำไปสู่การติดต่อกันที่ต่ำ
Arnis Lapsa

10

ตัวอย่างที่ไม่ใช่การเขียนโปรแกรมบางอย่างที่อาจช่วยให้คุณเห็นการใช้อินเตอร์เฟสที่เหมาะสมในการเขียนโปรแกรม

มีอินเทอร์เฟซระหว่างอุปกรณ์ไฟฟ้าและเครือข่ายไฟฟ้า - เป็นชุดของการประชุมเกี่ยวกับรูปร่างของปลั๊กและซ็อกเก็ตและแรงดัน / กระแสต่าง ๆ หากคุณต้องการนำอุปกรณ์ไฟฟ้าใหม่มาใช้ตราบใดที่ปลั๊กของคุณปฏิบัติตามกฎก็จะสามารถรับบริการจากเครือข่ายได้ สิ่งนี้ทำให้การขยายได้ง่ายมากและลบหรือลดค่าใช้จ่ายในการประสานงาน : คุณไม่ต้องแจ้งผู้ให้บริการไฟฟ้าเกี่ยวกับการทำงานของอุปกรณ์ใหม่ของคุณและทำข้อตกลงแยกต่างหากเกี่ยวกับวิธีเสียบอุปกรณ์ใหม่เข้ากับเครือข่าย

ประเทศมีมาตรวัดรางมาตรฐาน สิ่งนี้ทำให้แผนกแรงงานระหว่าง บริษัท วิศวกรรมที่วางรางและ บริษัท วิศวกรรมที่สร้างรถไฟวิ่งบนรางเหล่านั้นและทำให้ บริษัท รถไฟสามารถแทนที่และอัพเกรดรถไฟได้โดยไม่ต้องปรับปรุงระบบทั้งหมด

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

ตัวอย่างจากธรรมชาติ: ฉันไม่กระตือรือร้นกับ eats (), makeSound (), ย้าย (), ตัวอย่าง ฯลฯ พวกเขาจะอธิบายพฤติกรรมที่ถูกต้อง แต่พวกเขาไม่ได้อธิบายปฏิสัมพันธ์และวิธีการที่พวกเขากำลังเปิดใช้งาน ตัวอย่างที่ชัดเจนของอินเทอร์เฟซที่เปิดใช้งานการโต้ตอบในธรรมชาติจะทำอย่างไรกับการทำสำเนาเช่นดอกไม้ให้อินเทอร์เฟซบางอย่างกับผึ้งเพื่อให้เกิดการผสมเกสร


5

เป็นไปได้ทั้งหมดที่จะใช้ชีวิตทั้งชีวิตของคุณในฐานะนักพัฒนา. net และไม่เคยเขียนส่วนต่อประสานของคุณเอง ท้ายที่สุดเราก็รอดพ้นได้โดยไม่มีพวกเขามานานหลายทศวรรษและภาษาของเรายังคงทัวริงสมบูรณ์

ฉันไม่สามารถบอกคุณได้ว่าทำไมคุณถึงต้องการอินเทอร์เฟซ แต่ฉันสามารถให้รายการที่เราใช้ในโครงการปัจจุบันของเรา:

  1. ในรูปแบบปลั๊กอินของเราเราโหลดปลั๊กอินตามส่วนต่อประสานและให้ส่วนต่อประสานกับตัวเขียนปลั๊กอินเพื่อให้สอดคล้อง

  2. ในระบบการส่งข้อความของเราคลาสข้อความทั้งหมดใช้อินเทอร์เฟซเฉพาะและ "ไม่ได้ห่อ" โดยใช้อินเทอร์เฟซ

  3. ระบบการจัดการการกำหนดค่าของเรากำหนดอินเทอร์เฟซที่ใช้ในการตั้งค่าและดึงการตั้งค่า

  4. เรามีหนึ่งอินเทอร์เฟซที่เราใช้เพื่อหลีกเลี่ยงปัญหาการอ้างอิงแบบวงกลมที่น่ารังเกียจ (อย่าทำอย่างนี้ถ้าคุณไม่ต้องทำ)

ฉันเดาว่ามีกฎหรือไม่ก็คือใช้อินเทอร์เฟซเมื่อคุณต้องการจัดกลุ่มคลาสต่างๆภายในความสัมพันธ์แบบ is-a แต่คุณไม่ต้องการให้มีการใช้งานใด ๆ ในคลาสพื้นฐาน


5

ตัวอย่างรหัส (การรวมกันของแอนดรูกับส่วนเพิ่มเติมของฉันในสิ่งที่เป็นวัตถุประสงค์ของอินเทอร์เฟซ ), ที่ยังทำให้กรณีที่ว่าทำไมอินเตอร์เฟซแทนระดับนามธรรมในภาษาที่ไม่มีการสนับสนุนหลายมรดก (c # และ Java):

interface ILogger
{
    void Log();
}
class FileLogger : ILogger
{
    public void Log() { }
}
class DataBaseLogger : ILogger
{
    public void Log() { }
}
public class MySpecialLogger : SpecialLoggerBase, ILogger
{
    public void Log() { }
}

ขอให้สังเกตว่า FileLogger และ DataBaseLogger ไม่ต้องการอินเทอร์เฟซ (อาจเป็นคลาสพื้นฐานบทคัดย่อของ Logger) แต่ให้พิจารณาว่าคุณจำเป็นต้องใช้ตัวบันทึกบุคคลที่สามที่บังคับให้คุณใช้คลาสพื้นฐาน (สมมติว่ามันเปิดเผยวิธีการป้องกันที่คุณต้องการใช้) เนื่องจากภาษาไม่รองรับการสืบทอดหลายแบบคุณจึงไม่สามารถใช้วิธีการเรียนพื้นฐานแบบนามธรรมได้

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


4

ฉันใช้อินเทอร์เฟซแล้วและนี่คือการใช้งานล่าสุดของฉัน (ชื่อทั่วไป):

ฉันมีการควบคุมที่กำหนดเองมากมายบน WinForm ที่ต้องการบันทึกข้อมูลไปยังวัตถุทางธุรกิจของฉัน วิธีหนึ่งคือการโทรแต่ละตัวควบคุมแยกกัน:

myBusinessObject.Save(controlA.Data);
myBusinessObject.Save(controlB.Data);
myBusinessObject.Save(controlC.Data);

ปัญหาของการใช้งานนี้คือเมื่อใดก็ตามที่ฉันเพิ่มการควบคุมฉันจะต้องเข้าไปในวิธีการ "บันทึกข้อมูล" ของฉันและเพิ่มการควบคุมใหม่

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

foreach(Control c in Controls)
{
  ISaveable s = c as ISaveable;

  if( s != null )
      s.SaveToBusinessObject(myBusinessObject);
}

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

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


4

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

พฤติกรรมของสัตว์อาจเกี่ยวข้องกับการเดินการกินการวิ่ง ฯลฯ ดังนั้นคุณจึงกำหนดให้มันเป็นอินเตอร์เฟส

อีกตัวอย่างที่เป็นประโยชน์คือส่วนต่อประสาน ActionListener (หรือ Runnable) คุณจะใช้มันเมื่อคุณต้องการติดตามเหตุการณ์เฉพาะ ดังนั้นคุณจะต้องให้การใช้งานสำหรับactionPerformed(Event e)วิธีการในชั้นเรียนของคุณ (หรือคลาสย่อย) สำหรับอินเทอร์เฟซที่เรียกใช้ได้คุณให้การใช้งานสำหรับpublic void run()วิธีการนี้

นอกจากนี้คุณสามารถให้อินเทอร์เฟซเหล่านี้ถูกใช้งานโดยคลาสใด ๆ ก็ได้

อินสแตนซ์อื่นที่ใช้อินเทอร์เฟซ (ใน Java) คือการนำมรดกมาใช้ใน C ++


3
ได้โปรดพระเจ้าทำให้พวกเขาหยุดพูดสิ่งต่าง ๆ เช่นมรดกหลายประการเกี่ยวกับอินเทอร์เฟซ คุณไม่ได้รับส่วนต่อประสานในชั้นเรียน คุณIMPLEMENTมัน
Andrei Rînea

4

สมมติว่าคุณต้องการต้องการจำลองสิ่งที่น่ารำคาญที่อาจเกิดขึ้นเมื่อคุณพยายามเข้านอน

โมเดลก่อนอินเตอร์เฟส

ป้อนคำอธิบายรูปภาพที่นี่

class Mosquito {
    void flyAroundYourHead(){}
}

class Neighbour{
    void startScreaming(){}
}

class LampJustOutsideYourWindow(){
    void shineJustThroughYourWindow() {}
}

อย่างที่คุณเห็นชัดเจนว่า 'สิ่ง' หลายอย่างอาจสร้างความรำคาญเมื่อคุณพยายามนอน

การใช้คลาสที่ไม่มีอินเตอร์เฟส

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

class TestAnnoyingThings{
    void testAnnoyingThinks(Mosquito mosquito, Neighbour neighbour, LampJustOutsideYourWindow lamp){
         if(mosquito != null){
             mosquito.flyAroundYourHead();
         }
         if(neighbour!= null){
             neighbour.startScreaming();
         }
         if(lamp!= null){
             lamp.shineJustThroughYourWindow();
         }
    }
}

โมเดลที่มีอินเตอร์เฟส

เพื่อเอาชนะปัญหานี้เราสามารถแนะนำตัววนซ้ำป้อนคำอธิบายรูปภาพที่นี่

interface Annoying{
   public void annoy();

}

และนำไปใช้ในคลาส

class Mosquito implements Annoying {
    void flyAroundYourHead(){}

    void annoy(){
        flyAroundYourHead();
    }
}

class Neighbour implements Annoying{
    void startScreaming(){}

    void annoy(){
        startScreaming();
    }
}

class LampJustOutsideYourWindow implements Annoying{
    void shineJustThroughYourWindow() {}

    void annoy(){
        shineJustThroughYourWindow();
    }
}

การใช้งานกับอินเตอร์เฟส

ซึ่งจะทำให้การใช้งานของชั้นเรียนเหล่านี้ง่ายขึ้นมาก

class TestAnnoyingThings{
    void testAnnoyingThinks(Annoying annoying){
        annoying.annoy();
    }
}

ตกลง แต่ยังไม่ได้NeighbourและLampJustOutsideYourWindowยังต้องใช้งานAnnoyingหรือไม่
ละอองดาว

ใช่ขอบคุณที่ชี้ให้เห็น ฉันแก้ไขด้วยการเปลี่ยนแปลงนี้แล้ว
Marcin Szymczak

2

ตัวอย่างที่ง่ายที่สุดในการมอบคือตัวประมวลผลการชำระเงิน (Paypal, PDS และอื่น ๆ )

สมมติว่าคุณสร้างอินเทอร์เฟซ IPaymentProcessor ที่มีวิธีการ ProcessACH และ ProcessCreditCard

ตอนนี้คุณสามารถใช้งาน Paypal ได้อย่างเป็นรูปธรรม การทำให้วิธีการเหล่านี้เรียกใช้ฟังก์ชันเฉพาะของ PayPal

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


2

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

http://www.nmock.org/


2

ถ้าคุณเรียกดูแอสเซมบลี. NET Framework และเจาะลึกลงในคลาสพื้นฐานสำหรับวัตถุมาตรฐานใด ๆ คุณจะสังเกตเห็นอินเทอร์เฟซมากมาย (สมาชิกที่มีชื่อเป็น ISomeName)

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

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

ตัวอย่างคลาสสิก: หากไม่มีการใช้อินเทอร์เฟซ IDisposable คุณไม่สามารถใช้คำสำคัญ "using ()" การสร้างใน C # เพราะมันต้องการวัตถุที่ระบุเป็นพารามิเตอร์สามารถโยนไป IDisposable โดยปริยาย

ตัวอย่างที่ซับซ้อน: ตัวอย่างที่ซับซ้อนมากขึ้นคือคลาส System.ComponentModel.Component คลาสนี้ใช้ทั้ง IDisposable และ IComponent ส่วนใหญ่ถ้าไม่ใช่ทั้งหมดวัตถุ. NET ที่มีตัวออกแบบภาพที่เกี่ยวข้องจะใช้ IComponent เพื่อให้ IDE สามารถโต้ตอบกับคอมโพเนนต์ได้

สรุป: เมื่อคุณคุ้นเคยกับ. NET Framework มากขึ้นสิ่งแรกที่คุณจะทำเมื่อพบคลาสใหม่ใน Object Browser หรือภายในเครื่องมือ. NET Reflector (ฟรี) ( http://www.red-gate.com) / products / reflector / ) คือการตรวจสอบว่าคลาสใดที่สืบทอดมาและรวมถึงอินเตอร์เฟสที่ใช้ .NET Reflector นั้นดีกว่า Object Browser เพราะช่วยให้คุณเห็นคลาส Derived ได้เช่นกัน ที่ช่วยให้คุณเรียนรู้เกี่ยวกับวัตถุทั้งหมดที่เกิดขึ้นจากคลาสเฉพาะดังนั้นอาจเรียนรู้เกี่ยวกับฟังก์ชันการทำงานของกรอบที่คุณไม่ทราบว่ามีอยู่ สิ่งนี้มีความสำคัญอย่างยิ่งเมื่อมีการปรับปรุงหรือเพิ่มเนมสเปซใหม่ให้กับ


2

พิจารณาว่าคุณกำลังสร้างเกมยิงคนแรก ผู้เล่นมีปืนหลายกระบอกให้เลือก

เราสามารถมีอินเตอร์เฟซที่กำหนดฟังก์ชั่นGunshoot()

เราต้องการคลาสย่อยที่แตกต่างกันของGunคลาสคือShotGun Sniperเป็นต้น

ShotGun implements Gun{
    public void shoot(){
       \\shotgun implementation of shoot.
    } 
}

Sniper implements Gun{
    public void shoot(){
       \\sniper implementation of shoot.
    } 
}

คลาสนักกีฬา

ปืนมีปืนทั้งหมดในชุดเกราะของเขา ให้สร้าง a Listเพื่อแทนมัน

List<Gun> listOfGuns = new ArrayList<Gun>();

รอบปืนผ่านปืนของเขาเป็นและเมื่อจำเป็นต้องใช้ฟังก์ชั่น switchGun()

public void switchGun(){
    //code to cycle through the guns from the list of guns.
    currentGun = //the next gun in the list.
}

เราสามารถตั้งค่าปืนปัจจุบันโดยใช้ฟังก์ชั่นดังกล่าวข้างต้นและเพียงเรียก shoot()ฟังก์ชั่นเมื่อfire()มีการเรียก

public void fire(){
    currentGun.shoot();
}

พฤติกรรมของฟังก์ชั่นยิงจะแตกต่างกันไปตามการใช้งานที่แตกต่างกันของGunอินเตอร์เฟซ

ข้อสรุป

สร้างอินเตอร์เฟสเมื่อฟังก์ชันคลาสขึ้นอยู่กับฟังก์ชันจากคลาสอื่นซึ่งอาจมีการเปลี่ยนแปลงพฤติกรรมตามอินสแตนซ์ (วัตถุ) ของคลาสที่ใช้งาน

เช่นfire()ฟังก์ชั่นจากShooterคลาสคาดว่าปืน ( Sniper, ShotGun) เพื่อใช้งานshoot()ฟังก์ชั่น ดังนั้นหากเราเปลี่ยนปืนและไฟ

shooter.switchGun();
shooter.fire();

เราได้เปลี่ยนพฤติกรรมของfire()ฟังก์ชั่น


1

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


1

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

ตัวอย่างที่ดีของสิ่งนี้ในโลก NET คืออินเทอร์เฟซIDisposableซึ่งใช้กับคลาส Microsoft ใด ๆ ที่ใช้ทรัพยากรระบบที่ต้องถูกปล่อยด้วยตนเอง มันต้องการให้คลาสที่ใช้มันมีเมธอด Dispose ()

(วิธีการกำจัด () วิธีการนี้ยังเรียกโดยใช้ภาษาสร้างสำหรับVB.NETและC #ซึ่งใช้งานได้เฉพาะในIDisposables)

โปรดทราบว่าคุณสามารถตรวจสอบว่าวัตถุใช้อินเทอร์เฟซเฉพาะโดยใช้โครงสร้างเช่นTypeOf ... Is(VB.NET), is(C #), instanceof(Java), ฯลฯ ...


1

อาจมีหลายคนที่ตอบไว้แล้วสามารถใช้อินเตอร์เฟสเพื่อบังคับใช้พฤติกรรมบางอย่างระหว่างคลาสที่จะไม่ใช้พฤติกรรมเหล่านั้นในลักษณะเดียวกัน ดังนั้นโดยการใช้อินเทอร์เฟซคุณกำลังบอกว่าคลาสของคุณมีลักษณะการทำงานของอินเทอร์เฟซ อินเทอร์เฟซ IAnimal จะไม่เป็นอินเทอร์เฟซทั่วไปเนื่องจากคลาส Dog, Cat, Bird ฯลฯ เป็นสัตว์ชนิดหนึ่งและอาจขยายออกไปซึ่งเป็นกรณีของการสืบทอด อินเทอร์เฟซจะเหมือนพฤติกรรมสัตว์ในกรณีนี้เช่น IRunnable, IFlyable, ITrainable เป็นต้น

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

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

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


1

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

มีการแลกเปลี่ยนที่นี่เช่นเคย: ความยืดหยุ่นมากกว่าการบำรุงรักษา อันไหนสำคัญกว่ากัน? ไม่มีคำตอบ - มันขึ้นอยู่กับโครงการ แต่เพียงจำไว้ว่าทุกโปรแกรมจะต้องได้รับการดูแล ...

ดังนั้นคำแนะนำของฉัน: อย่าใช้อินเทอร์เฟซจนกว่าคุณต้องการจริงๆ (ด้วย Visual Studio คุณสามารถแยกอินเทอร์เฟซจากคลาสที่มีอยู่ใน 2 วินาที - ดังนั้นอย่ารีบร้อน)

ต้องบอกว่าเมื่อไหร่ที่คุณจำเป็นต้องสร้างส่วนต่อประสาน?

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

และใช้งานได้: o)

ข้อยกเว้นหนึ่ง: เมื่อฉันเมื่อต้องจำลองวัตถุอินเทอร์เฟซใช้งานได้ง่ายกว่ามาก ดังนั้นฉันมักจะสร้างส่วนต่อประสานสำหรับสิ่งนี้

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

ขอแสดงความนับถือ Sylvain


1

อินเทอร์เฟซจะปรากฏชัดเมื่อคุณเป็นนักพัฒนาห้องสมุด (คนที่รหัสสำหรับ coders อื่น) ส่วนใหญ่ของเราเริ่มต้นในฐานะนักพัฒนาแอปพลิเคชันที่เราใช้ API ที่มีอยู่และไลบรารีการเขียนโปรแกรม

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

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

นอกจากนี้ยังเห็นนี้คำถามที่เกี่ยวข้องเกี่ยวกับการเขียนโปรแกรมเพื่อมีอินเตอร์เฟซ


1

มีวัตถุประสงค์มากมายสำหรับการใช้อินเทอร์เฟซ

  1. ใช้ในพฤติกรรม polymorphic ที่คุณต้องการเรียกวิธีการเฉพาะของคลาสเด็กที่มีอินเทอร์เซซมีการอ้างอิงถึงระดับเด็ก

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

  3. เพื่อลดการใช้หน่วยความจำโดยการโหลดวิธีการเฉพาะในชั้นเรียน เช่นถ้าคุณมีวัตถุธุรกิจสามชิ้นและถูกนำมาใช้ในคลาสเดียวคุณสามารถใช้สามส่วนต่อประสานได้

เช่น IUser, IOrder, IOrderItem

public interface IUser()
{

void AddUser(string name ,string fname);

}

// Same for IOrder and IOrderItem
//


public class  BusinessLayer: IUser, IOrder, IOrderItem

{    
    public void AddUser(string name ,string fname)
    {
        // Do stuffs here.
    }

    // All methods from all interfaces must be implemented.

}

หากคุณต้องการเพิ่มผู้ใช้ให้ทำดังนี้:

IUser user = new (IUser)BusinessLayer();

// It will load  all methods into memory which are declared in the IUser interface.

user.AddUser();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.