#java #oop
#java #ооп
Вопрос:
В Java абстрактные классы дают возможность определять как конкретные, так и абстрактные методы, тогда как интерфейсы дают возможность реализовывать только абстрактные методы. Я считаю, что переопределение методов в подклассах / реализациях возможно в обоих случаях, поэтому, в чем реальное преимущество одного над другим (интерфейсы против абстрактных классов в Java)?
Комментарии:
1. Пожалуйста, выберите один язык. Соответствующие ответы могут сильно отличаться.
2. @Oli — итак, я должен опубликовать новый вопрос — Чем отличается ООП на разных языках, таких как java, php, .net 🙂
3. Нет, потому что этот вопрос был бы слишком широким. Вопросы по SO должны быть конкретными .
Ответ №1:
Интерфейсы предназначены для случаев, когда вы хотите сказать: «Мне все равно, как вы это делаете, но вот что вам нужно сделать».
Абстрактные классы предназначены для случаев, когда вы хотите сказать: «Я знаю, что вы должны делать, и я знаю, как вы должны это делать в некоторых / многих случаях».
Абстрактные классы имеют несколько серьезных недостатков. Например:
class House {
}
class Boat {
}
class HouseBoat extends /* Uh oh!! */ {
// don't get me started on Farmer's Insurance "Autoboathome" which is also a helicopter
}
Вы можете получить доступ через интерфейс:
interface Liveable {
}
interface Floatable {
}
class HouseBoat implements Liveable, Floatable {
}
Теперь абстрактные классы также очень полезны. Для примера рассмотрим класс AbstractCollection. Он определяет поведение по умолчанию для очень распространенных методов во всех коллекциях, таких как isEmpty()
и contains(Object)
. Вы можете переопределить это поведение, если хотите, но … действительно ли поведение для определения того, является ли коллекция пустой, может измениться? Обычно это будет size == 0
. (Но это может иметь большое значение! Иногда вычислять размер дорого, но определить, является ли что-то пустым или нет, так же просто, как посмотреть на первый элемент.)
И поскольку он не будет часто меняться, действительно ли разработчику стоит тратить время на реализацию этого метода каждый … отдельный … раз… для каждого метода в этой категории «решаемых»? Не говоря уже о том, что когда вам нужно внести в него изменения, у вас будет дублирование кода и пропущенные ошибки, если вам придется повторно внедрять его повсюду.
Комментарии:
1. Также полезно в средних / крупных проектах согласовать интерфейсы, которые будут поддерживать определенные модули. Вам нужно знать, чего вы можете ожидать от других модулей, а другие модули имеют представление о том, чего они могут ожидать от вашего модуля.
2. Согласен. Он легче поддается изменению реализации.
3. 1 lol в «// не заставляйте меня начинать с фермерского страхового «Autoboathome», который также является вертолетом»
4. После того, как в Java 8 в интерфейсы была добавлена поддержка методов по умолчанию, здесь теперь еще больше профессионалов, использующих интерфейсы.
5. @OleksandrPapchenko верно, истинно — в недавнем проекте я обнаружил, что использую интерфейсы 3 к 1 для абстрактных классов. Вам действительно нужно определить только один или два метода (обычно геттеры), а остальное поведение, построенное на этих моделях поведения, будет жить в интерфейсе вместо копирования и вставки в 20 различных классов.
Ответ №2:
Интерфейсы полезны, потому что Java не имеет множественного наследования (но вы можете реализовать столько интерфейсов, сколько захотите).
Абстрактные классы полезны, когда вам нужно конкретное поведение базового класса.
Ответ №3:
Факты таковы-
- Java не поддерживает множественное наследование
- Может быть реализовано несколько интерфейсов
- В абстрактном классе может быть реализовано несколько методов
Эти факты можно использовать, чтобы склонить преимущество в пользу интерфейсов или абстрактных классов.
Если существует более одного поведения, которое класс должен совместно использовать с другими классами, выигрывают интерфейсы. Если определение метода должно быть разделено / переопределено другими классами, выигрывают абстрактные классы.
Ответ №4:
Класс может реализовывать несколько интерфейсов, тогда как он может только расширять один класс (абстрактный или конкретный), поскольку Java не поддерживает множественное наследование.
Ответ №5:
В ООП (в основном независимом от конкретного языка) абстрактные классы представляют собой механизм повторного использования иерархии классов для поведения и структуры, который сам по себе не является полным. Интерфейсы — это механизм для спецификации требований к модулю (например, классу) независимо от конкретной реализации. Все остальные различия являются техническими деталями, важным является различное использование.
Ответ №6:
Вы не переопределяете интерфейс. Вы его реализуете.
Написание интерфейса дает разработчикам возможность реализовать ваш интерфейс, а также другие интерфейсы в дополнение к наследованию от базового класса.
Абстрактные классы могут быть частично или полностью реализованы.Пометка абстрактного класса просто мешает вам создать экземпляр объекта этого типа.
Ответ №7:
-Метод без какой-либо реализации является абстрактным методом, всякий раз, когда класс содержит один или более абстрактных методов, он должен быть объявлен как абстрактный класс
-Интерфейс полностью абстрактен, в нем не может быть конструктора, экземпляра и статических блоков, и он содержит только два типа членов 1. общедоступный абстрактный метод 2.общедоступная статическая конечная переменная
* Оба экземпляра не могут быть созданы, но ссылка может быть создана.
* Какой из них подходит лучше, зависит от приложения — Интерфейсы полезны, потому что классы Java не будут поддерживать множественное наследование, но интерфейсы поддерживают.
-Абстрактные классы полезны, когда вам нужно конкретное поведение базового класса.
Ответ №8:
Основные преимущества интерфейса перед абстрактным классом заключаются в преодолении возникновения проблемы diamond и достижении множественного наследования. В Java не предусмотрено решения проблемы diamond с использованием классов.По этой причине множественное наследование является блочным использованием классов в java. Итак, для достижения множественного наследования мы используем interface .
Ответ №9:
class Animal
{ void move(){} }
class Bird
{ void move(){fly} }
class Fish
{ void move(){swim} }
Теперь, если класс Animal является абстрактным классом, подобным
Animal a;
a= new Bird(); or a = new Fish()
Здесь абстракция работает хорошо, но если имеется 100 объектов, подобных Animal a[100]
;
Вы не можете написать new Bird().move
or new Fish().move
100 раз
Используйте интерфейс и пишите a[i].move
. Он будет различаться как bird или fish, и это move()
будет вызвано
Во-вторых, он поддерживает множественное наследование, поскольку класс A
может реализовать любое количество интерфейсов.
Ответ №10:
Потрясающие ответы!!
Я тоже хочу высказать свое мнение об интерфейсе.
Как следует из названия, это interface, что означает, что он обеспечит интерфейс между двумя классами.
Это помогает классу или интерфейсу поддерживать множественное поведение одновременно.
Кто когда-либо имел интерфейс, может получить доступ к поведению класса, согласованному с интерфейсом.
interface teacher
{
//methods related to teacher
}
interface student
{
//methods related to student
}
interface employee
{
//methods related to employee
}
class Person:teacher,student,employee
{
//definition of all the methods in teacher,student, employee interface
//and method for person
}
Теперь здесь, какой бы класс ни имел teacher
интерфейс, он будет иметь доступ только к teacher
поведению пользователя.
Аналогично класс или модуль, имеющий student
интерфейс, будет иметь доступ только к student
поведению пользователя.
Используя абстрактный класс, это вообще невозможно.
Надеюсь, это добавит несколько дополнительных моментов. 🙂
Счастливого кодирования!!.