Здравствуйте, Ikemefula, Вы писали:
I>Наоборот, это нормально, но только в определенных рамках. Т.е. когда сохраняется контракт, предусловия, постусловия и тд. Как только это ломается, например метод Add по факту начинает удалять, это конечно же паскудство.
Контракт может сохраняться, я не спорю. Но зачем делать так:
Interface --> Impl1 --> Impl2
Когда логичнее так:
Interface --> Impl1
+-> Impl2
А общие данные и методы можно вынести в общего абстрактного предка. Или отдельно в общего мембера.
У первого варианта в том, что объект типа Impl2 является также объектом типа Impl1, который с точки зрения функциональности, как правило, не ведёт себя как объект типа Impl1. Например Impl1 рисует на экране белым цветом по чёрному, а Impl2 чёрным по белому. А интерфейс и инварианты могут быть при этом одинаковые.
Я не рассматриваю случаи, когда Impl2 делает совсем то же самое, что и Impl1, но скажем оптимизирован для более узкого круга задач.