Навіщо потрібен інтерфейс в java

При extends методи годі й перевизначати, а при implements методи обов'язково потрібно перевизначити, так навіщо їх перевизначати, якщо можна на пряму створити методи в потрібних класах. Просто, я не зовсім розумію як роблять API) Напевно просто не зіткнувся з завданнями, які вирішують абстрактні класи і інтерфейси)

При extends методи годі й перевизначати - тільки якщо успадковується від конкретного класу (тобто якщо вони вже десь хоч раз були визначені)! Якщо ж успадковується від абстрактного класу, то або і сам успадковує клас повинен бути все ще абстрактним, або таки доведеться метод імплементувати :) Тут фішка зовсім в іншому!

Спадкування від абстрактних класів дозволяє "розмазати" імплементацію окремих методів по різних рівнях успадкування. На кожному рівні імплементуємо те, що до нього відноситься, а інші способи залишаємо абстрактними, і імплементуємо їх на інших рівнях.

Інтерфейс ж вимагає, зрозуміло, імплементувати всі - на те він і контракт. Так що, інтерфейс використовується саме для закріплення контракту, а абстрактний клас - для структурування імплементації цього контракту.

ось є обговорення У чому суть інтерфейсів в програмуванні?
Я б сказав що інтерфейс це контракт між шарами додатки. У вас є шари дао, сервісів, може секьюреті і ще щось. Між ними є інтерфейси. А значить ви без праці можете замінити реалізацію якогось шару інший реалізацією. Наприклад щось подібне робить спринг коли створює додаткову прошарок для управління транзакціями над дао. Так само це буває зручно при тестуванні коли для тестів ви пишете Mock об'єкт

Full-stack developer (Symfony, Angular)

Класичний приклад - клас логгер. Можна просто не паритися і зробити клас Logger зі своєю реалізацією, і всюди в клієнтському коді (тобто той код, який цей клас буде використовувати) зав'язати на цей клас.

Але чу, тепер логи у нас повинні зберігатися не в файлах а в базі, раптово так. У нас змінюється конструктор, у нас змінюється реалізація всіх методів (припустимо що у нас він один, log (string message, int level, string category);

І добре якщо у нас дотримується принцип інверсії залежностей, тоді то що ми конструктор поміняли ніяк не позначиться на кліентсоком коді бо інстанси просто йому дається а він нічого не знає про те як створювати нім. Але у нас постає делема, або пошуком-заміною міняти тип в клієнтському коді, або успадковуватися і просто замінювати реалізацію. В цьому плані успадкування працювати буде так як ми хочемо, але навіщо?

З інтерфейсом у нас є гарний інтерфейс, є його реалізації, якщо у нас є контейнер залежностей то ми можемо прив'язати конкретну реалізацію до інтерфейсу і там де потрібно цей інтерфейс буде автоматом засунута потрібна реалізація. Заміна реалізації - змінити конфіг DI.

Так само, якщо вам потрібно часто міняти інтерфейс то у вас вже якісь проблеми з побудовою архітектури. Інтерфейс повинен бути простим і повинен робити щось одне.

А взагалі, почитайте про GRASP і SOLID.

Інверсія залежності, конфиг DI, архітектура - ви впевнені що людина задав таке питання розуміє ці речі? = D до того ж ваша відповідь сильно прив'язаний до IoC і DI, що м'яко кажучи є оверхедів при відповіді на питання "для чого потрібні інтерфейси".

@NekitoSP Ви маєте рацію) В низу ще страшніше пояснення)

Інтерфейс - це контракт, за яким з вашим кодом взаємодіють.

А навіщо мені укладати контракт якщо, я без контракту нормально можу створити методи і працювати з ними. Виходить при подальшому розширення коду з інтерфейсом буде зручно. Я правильно зрозумів?