ฉันควรใช้อินเตอร์เฟสโดยตรงหรือให้ซูเปอร์คลาสทำหรือไม่


14

มีความแตกต่างระหว่าง

public class A extends AbstractB implements C
{...}

เมื่อเทียบกับ ...

public class A extends AbstractB
{...}
abstract class AbstractB implements C
{...}

ฉันเข้าใจว่าในทั้งสองกรณีคลาส A จะจบลงที่สอดคล้องกับส่วนต่อประสาน ในกรณีที่สองสามารถให้การดำเนินงานสำหรับวิธีการในอินเตอร์เฟซAbstractB Cนั่นคือความแตกต่างเท่านั้น?

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


3
ข้อเสนอแนะเกี่ยวกับชื่อเรื่อง: ฉันควรจะใช้อินเทอร์เฟซโดยตรงหรือให้ซูเปอร์คลาสทำ
Jeanne Boyarsky

คำตอบ:


20

ทุกอย่างขึ้นอยู่กับว่าAbstractB implements Csemantically คือถ้ามันใช้ความหมายAbstractBเพื่อนำCไปใช้จริง

ถ้าเรานำตัวอย่างที่เป็นรูปธรรมความแตกต่างทางความหมายจะชัดเจน

ถ้า A = Dog, AbstractB = สัตว์, C = IBark

ทางเลือกเดียวที่สมเหตุสมผลคือ

class Dog extends Animal implements IBark{

มันไม่สมเหตุสมผลเลยเพราะสิ่งนี้จะบ่งบอกว่าสัตว์ทุกตัวเห่า

class Animal implements IBark{

ความแตกต่างอื่น ๆ เข้ามาเล่นถ้าคุณมีมากกว่าเพียงแค่การสืบทอดจากclass A AbstractBใน # 1 พวกเขาไม่จำเป็นต้องใช้ C ใน # 2 พวกเขาทั้งหมดถูกบังคับให้ใช้ C


1
+1 ชัดเจนกว่าคำตอบของฉัน!
Hand-E-Food

นอกจากนี้หากเป็นอินเตอร์เฟซHeterotrophดูเหมือนว่าเหมาะสมที่จะทำให้การดำเนินการAnimal Heterotrophหากคุณคาดหวังว่าสัตว์เห่าชนิดอื่น ๆ จำนวนมากและต้องการที่จะปฏิบัติต่อพวกมันในแบบเดียวกันคลาสอื่นBarkingAnimal extends Animal implements IBarkก็จะเป็นหนทางไป
scarfridge

@scarfridge ที่จริงฉันคาดหวังว่าสัตว์จะขยายHeterotrophแต่ขอบคุณสำหรับการป้อนข้อมูลของคุณ
Karthik T

2

วิธีง่าย ๆ ในการกำหนดความสัมพันธ์ของการสืบทอดที่เหมาะสมไม่ใช่การดูคลาสเอง แต่ใช้รหัสที่เรียกเมธอดบนคลาสเหล่านั้น ที่ไหนสักแห่งในรหัสของคุณคุณมีสิ่งที่ต้องการหรือAbstractB b = new A(); otherObject.addAbstractB(this);ไม่ว่าจะด้วยวิธีใดคุณจะใช้AbstractBการอ้างอิงนั้นในภายหลังเพื่อทำการเรียกใช้เมธอดต่างๆ

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


2

ไม่ใช่วัตถุประสงค์ของเอกสาร "ซ่อน" มันอนุญาตให้คุณร่าย AbstractB และ subclasses ทั้งหมดของ C มีสามลักษณะจริง ๆ

public class A extends AbstractB implements C
public class AbstractB

ฉันจะใช้อันนี้ถ้า AbstractB ไม่ได้ใช้ C อย่างมีเหตุผลแม้ว่ามันจะไม่ได้ให้วิธีการ แต่ก็มีความหมาย เช่นสุนัขขยายสัตว์ดำเนินการ Wag มันไม่สมเหตุสมผลเลยที่สัตว์ทุกตัวจะวัก โปรดทราบว่าวิธีการนี้ไม่ได้ขัดขวาง AbstractB จากการจัดทำการนำไปใช้จริง

public class A extends AbstractB
public AbstractB implements C

ฉันจะใช้อันนี้ถ้าฉันต้องการ subclasses ทั้งหมดเพื่อใช้อินเตอร์เฟซและมันเหมาะสมสำหรับพวกเขาทั้งหมดที่จะทำ เช่น Beagle ขยาย AbstractDog ใช้ Wag

public class A extends AbstractB implements C
public class AbstractB implements C

อันนี้ซ้ำซ้อน แต่อาจเพิ่มความชัดเจน


ฉันคิดว่า "AbstractC" (ซึ่งไม่มีอยู่ในคำถาม) ในวรรค 2 ควรเปลี่ยนเป็น "AbstractB" ฉันไม่สามารถแก้ไขได้เนื่องจาก edist ต้องมีอย่างน้อย 6 ตัวอักษร
cellepo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.