Здравствуйте, _NN_, Вы писали:
_NN>В каком плане поменяли контракт ?
Добавление метода в интерфейс. Это изменение контракта (даже если оно non breaking).
_NN>Какую проблему вы здесь видите ?
В этом теоретическом примере вижу следующие проблемы
— интерфейс более не абстракция.
— интерфейс знает о реализациях, иначе откуда такая уверенность что дефолтный G() подходит для всех реализаций интерфейса.
— если по какой-то причине G() гарантированно подходит для любой реализации, то он может вполне себе быть extension методом.
— программист реализации может просто не заметить добавления G(), который будет не корректный для его реализации. Но в проекте IA.G() рано или поздно кто-то вызовет.
_NN>Интерфейс всё ещё остается интерфейсом. _NN>Наследоваться от двух классов нельзя в отличии от реализации множества интерфейсов.
Только это не основное свойство интерфейса. Интерфейс в первую очередь это абстракция, а теперь можно затянуть в него реализацию.
Не лучше было бы для таких кейсов ввести что-то типа "abstract base class" который бы и реализовывал такое поведение (по сути ведя себя как интерфейс с дефолтными методами)? А пользователю библиотеки уже выбирать наследоваться от интерфейса или такого класса.