В некоторых рекомендациях указано, что вы должны использовать интерфейс, если хотите определить контракт для класса, где наследование нечеткое (IDomesticated
) и наследование, когда класс является расширением другого (Cat : Mammal
, Snake : Reptile
), бывают случаи, когда (на мой взгляд) эти рекомендации входят в серое пространство.Когда использовать интерфейсы или абстрактные классы? Когда использовать оба?
Например, моя реализация была Cat : Pet
. Pet
- абстрактный класс. Должен ли он быть расширен до Cat : Mammal, IDomesticated
, где Mammal
является абстрактным классом, а IDomesticated
- это интерфейс? Или я вступаю в противоречие с принципами (хотя я не уверен, будет ли в будущем класс Wolf
, который не сможет наследовать от Pet
)?
Переход от метафорического Cat
s и Pet
s, допустим, у меня есть классы, которые представляют источники для входящих данных. Все они должны каким-то образом реализовать ту же базу. Я мог бы реализовать некоторый общий код в абстрактном классе Source
и наследовать его. Я мог бы также просто создать интерфейс ISource
(который чувствует себя более «правильным» для меня) и повторно реализовать общий код в каждом классе (который менее интуитивно понятен). Наконец, я мог «взять пирог и съесть его», сделав как абстрактный класс, так и интерфейс. Что лучше?
Эти два случая поднимают баллы за использование только абстрактного класса, только интерфейс и использование как абстрактного класса, так и интерфейса. Являются ли эти все действительные выборы или существуют «правила», когда их следует использовать над другим?
Я хотел бы уточнить, что, «используя как абстрактный класс и интерфейс», который включает в себя случай, когда они по существу представляют собой то же самое (Source
и ISource
оба имеют те же члены), но класс добавляет общую функциональность, в то время как интерфейс указывает контракт.
Также стоит отметить, что этот вопрос в основном относится к языкам, которые не поддерживают множественное наследование (например, .NET и Java).
Я хотел бы отметить, что я видел несколько вопросов «Интерфейс против абстрактных классов», но в этом вопросе меня больше всего интересует, когда использовать * оба * интерфейса и абстрактные классы (если это действительная вещь.) – Blixt
Возможный дубликат [Интерфейс против абстрактного класса (общий OO)] (http://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo) –
Возможный дубликат [Когда использовать интерфейс вместо абстрактного класса и наоборот?] (Http://stackoverflow.com/questions/479142/when-to-use-an-interface-instead-of-an-abstract-class-and -vice-versa) – nawfal