

Первая возникающая мысль: что же теперь с множественной имплементацией? Ведь она никуда не делась, а реализация методов появилась. Мы получили те же проблемы, от которых избавлял запрет на множественное наследование? Или были предусмотрены какие-то механизмы, позволяющие предотвратить возможную неоднозначность?
Вторая мысль: чем теперь отличается интерфейс от абстрактного класса?
Мысль первая: да, разработаны механизмы. И теперь всё не так просто, как было раньше. Если класс имплементирует несколько интерфейсов, содержащих методы с одинаковой сигнатурой, то в этом классе нужно обязательно переопределить реализацию такого метода. Собственно, её можно просто скопипастить из нужного интерфейса. Если методы будут отличаться набором параметров, то в итоге класс получит перегруженные методы, что проблем не вызывает. Если методы будут отличаться только возвращаемым типом, то компилятор выдаст ошибку. Со статическими методами дело обстоит проще – они принадлежат каждый своему интерфейсу и больше никому. Создание одноименного статического метода в классе ни на что не повлияет. Обратиться из класса к статическому методу интерфейса можно по его имени, так что конфликтов имён не возникнет. Вызвать статический метод через ссылочную переменную нельзя, поэтому и здесь конфликтов не будет.
Добавление реализации в интерфейсы позволяет избежать создания промежуточных классов-адаптеров, которые позволяли не писать реализацию для новых методов интерфейса во всех классах, которые его имплементрировали.
Вопрос второй: так в чём же отличие? В целом, это то же самое, что спросить: чем светофор отличается от ёлочной гирлянды? Оба светятся и мигают разными цветами. Разница как и раньше - в назначении.
Интерфейс наделяет объекты своим поведением. При этом сами объекты могут не иметь друг к другу никакого отношения. Например, интерфейс «Летающий» может реализовывать и муха, и самолёт, и даже подушка. Реализация данного интерфейса гарантирует, что объект имеет метод «лететь». Как он будет это делать, не интересует никого кроме этого объекта. Т.о. интерфейс обеспечивает использование объекта в любом контексте, в котором этот интерфейс объявлен.
Абстрактные классы объединяют однотипные классы для уменьшения количества кода, наделяют их необходимым состоянием и поведением, повышают их уровень абстракции. Т.е. муху от самолёта мы уже не отнаследуем. Технически это, конечно, возможно, но не надо так (с). Но можно создать абстрактный класс «Самолёт» с абстрактными методами: «влететь», «лететь», «приземлиться», «заправиться». Тогда любая отнаследованная от него модель самолёта будет обязана реализовать эти методы, поскольку без этих методов это будет уже не самолёт.
Интерфейс – более высокий уровень абстракции, чем абстрактный класс.