Не один раз написано о том, в чем разница между интерфейсом и абстрактным классом. В большинстве случаев разговор заканчивается фразами, сводящимися к следующему: "Абстрактный класс — это абстрактный класс, а интерфейс — это интерфейс..."
Могли бы вы ответить на простой вопрос: В каких случаях при проектировании вы делаете выбор в пользу интерфейса, а в каких — в пользу абстрактного класса? Какими признаками должны обладать сущности предметной области, чтобы быть отнесенными к интерфейсам? А к абстрактным классам?
Я думаю так или иначе все сталкиваются с предметной областью . И наверняка многие имеют опыт ее анализа. Очень хотелось бы зачерпнуть немного ваших знаний .
P.S. Разумеется, вопрос относиться к конкретному языку — Java, но и к понятию "интерфейс" как таковому.
03.07.06 13:19: Перенесено модератором из 'Java' — Blazkowicz
Re: Проектирование: интерфейс vs абстрактный класс
Я вообще не вижу смысла в а,страктных классах кроме как инкапсуляция общей (generic) или default логики всех (или большинства) имплементаций интерфейса.
Пример из Swing'а:
interface TableModel
abstact class AbstactTableModel implments TableModel — абстрактный класс с default логикой которая подходит большинству имплементаций TableModel
class OrdersTableModel extends AbstactTableModel — пользуется default логикой определенной в AbstactTableModel, там где надо переопределяет методы.
Мне кажется что вся эта дискуссия пошла из С++ где не было интерфейсов и вместо них использовались абстрактные классы (но там есть множественное наследование ), соответсвенно при переходе на Java часто возникает вопрос а зачем еще интерфейсы.
Re[2]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, boluba, Вы писали:
B>Не один раз написано о том, в чем разница между интерфейсом и абстрактным классом. В большинстве случаев разговор заканчивается фразами, сводящимися к следующему: "Абстрактный класс — это абстрактный класс, а интерфейс — это интерфейс..."
Интерфейсы были введены в Java, сколько бы не говорили о "принципах ОО", чтобы решить проблему множественного наследования. В Java нельзя множественно наследовать классы, но можно это обойти с помощью интерфейсов. В результате — никаких "ромбиков" и прочих "перегрузок" нет.
B>Могли бы вы ответить на простой вопрос: В каких случаях при проектировании вы делаете выбор в пользу интерфейса, а в каких — в пользу абстрактного класса? Какими признаками должны обладать сущности предметной области, чтобы быть отнесенными к интерфейсам? А к абстрактным классам?
Любой интерфейс — это то что лежит сверху. С кнопками. Чего там внутри — не важно. Есть кнопки и надписи на них. чтобы определить их — нужен интерфейс.
Абстрактный класс — это базовая прослойка, между интерфейсом и всем разнообразием, его реализующим. Ну например ControlPanel — интерфейс, AbstractControlPanel implements ControlPanel — базовая реализация, DefaultControlPanel extends AbstractControlPanel — какая то реализация.
На мой взгляд, хорошим примером продуманной архитекруты можно считать Swing. Там есть (не всегда конечно) то о чем я говорил. Например ListModel, AbstractListModel и DefaultListModel. Ну и так далее.
А вот Collections Framework на мой взгляд спроектирован ужастно. Взять хотябы List, AbstractList и ArrayList. Вроде все тоже самое, но внутри все сделано по-дурацки.
Re: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, boluba, Вы писали:
B>Не один раз написано о том, в чем разница между интерфейсом и абстрактным классом. В большинстве случаев разговор заканчивается фразами, сводящимися к следующему: "Абстрактный класс — это абстрактный класс, а интерфейс — это интерфейс..."
Поиск так же показывает много других интересных постов по теме.
B>Могли бы вы ответить на простой вопрос: В каких случаях при проектировании вы делаете выбор в пользу интерфейса, а в каких — в пользу абстрактного класса? Какими признаками должны обладать сущности предметной области, чтобы быть отнесенными к интерфейсам? А к абстрактным классам?
Честно говоря никогда не приходилось сталкиватся с такой проблемой выбора. Вроде всегда ясно где что приемнять.
B>Я думаю так или иначе все сталкиваются с предметной областью . И наверняка многие имеют опыт ее анализа. Очень хотелось бы зачерпнуть немного ваших знаний .
А мне хотелось бы посмотреть на пример (не оторваный от жизни) в котором на первый взгляд одинаково хорошо подходят и абстрактный класс и интерфейс.
B>P.S. Разумеется, вопрос относиться к конкретному языку — Java, но и к понятию "интерфейс" как таковому.
Вообще-то у нас есть такие форумы как проектирование и философия.
Re[2]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, aefimov, Вы писали:
A>А вот Collections Framework на мой взгляд спроектирован ужастно. Взять хотябы List, AbstractList и ArrayList. Вроде все тоже самое, но внутри все сделано по-дурацки.
не понял наезда? это то же самое что "Взять хотяб американцев, тоже люди, но сделаны как-то по-дурацки". Объясни конкретно что именно в Collections "сделано по-дурацки"
Re[3]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, Lucker, Вы писали:
L>не понял наезда? это то же самое что "Взять хотяб американцев, тоже люди, но сделаны как-то по-дурацки". Объясни конкретно что именно в Collections "сделано по-дурацки"
Ну посмотри как сделан AbstractList. Мало того что абстрактные методы перегружают методы интерфейса, так еще там полно методов вот таких:
public Object set(int index, Object element) {
throw new UnsupportedOperationException();
}
Я конечно понимаю, это чтоб "делать mutable коллекции" и не парится. Только это не фига не правильно, базовая функциональность не должна запрещать вызов методов, объявленных в интерфейсе — это мягко говоря, бяка.
Re[3]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, malkolinge, Вы писали:
M>Интерфейс необходимо использовать тогда, когда классы различных иерархий должны иметь возможность единообразной работы.
Это понятно. Вопрос был не когда использовать интерфейсы. А как выбрать между интерфейсом и абстрактным классом
Re: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, boluba, Вы писали:
B>Могли бы вы ответить на простой вопрос: В каких случаях при проектировании вы делаете выбор в пользу интерфейса, а в каких — в пользу абстрактного класса?
Выдержка из книги Горький вкус джава:
1. Если реализация может измениться, всегда используйте интерфейсы. При использовании абстрактных классов реализация может фиксироваться
2. Интерфейсы применяются для описания дополнительных возможностей (Printable, Serializable, Cloneable)
3. Интерфейсы используются в тех случаях, когда реализация по умолчанию не задана.
4. Абстрактные классы используются при частичном определении реализации по умолчанию
5. Иногда интерфейсы могут использоваться в сочетании с абстрактными классами для создания фиксированного интерфейса, комбинируемого с частичной реализацией. Такая комбинация продоставляет удобства частичной реализации с гибкостью интерфейсов.
суть в простоте, а простота в сути
Re: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, boluba, Вы писали:
B>Не один раз написано о том, в чем разница между интерфейсом и абстрактным классом. В большинстве случаев разговор заканчивается фразами, сводящимися к следующему: "Абстрактный класс — это абстрактный класс, а интерфейс — это интерфейс..."
B>Могли бы вы ответить на простой вопрос: В каких случаях при проектировании вы делаете выбор в пользу интерфейса, а в каких — в пользу абстрактного класса? Какими признаками должны обладать сущности предметной области, чтобы быть отнесенными к интерфейсам? А к абстрактным классам?
B>Я думаю так или иначе все сталкиваются с предметной областью . И наверняка многие имеют опыт ее анализа. Очень хотелось бы зачерпнуть немного ваших знаний .
B>P.S. Разумеется, вопрос относиться к конкретному языку — Java, но и к понятию "интерфейс" как таковому.
Если очень кратко:
абстрактный класс может содержать реализацию.Иногда это удобно.
Если приложение правильно проектируется с точки зрения ООП, то очень часто самый первый класс в цепочке наследования — абстрактный.
Все стальное — в посте выше, там более подробно.
A> public Object set(int index, Object element) {
A> throw new UnsupportedOperationException();
A> }
A>
A>Я конечно понимаю, это чтоб "делать mutable коллекции" и не парится. Только это не фига не правильно, базовая функциональность не должна запрещать вызов методов, объявленных в интерфейсе — это мягко говоря, бяка.
Тут можно спорить. Использование UnsupportedOperationException прямо и подробно описано в документации по Collections Framework. Насколько я понимаю, вы считаете, что раз уж класс реализует интерфейс (контракт), то должен его реализовывать (исполнять) полностью. Но если еще раз подумать, то выброс UnsupportedOperationException является неотемлемой частью контракта в данном контексте, не находите? На ваш взгляд было бы лучше вместо десятка интерфейсов и базовых реализаций иметь сотни конкретных частных решений, не выбрасывающих UnsupportedOperationException?
Re[2]: Проектирование: интерфейс vs абстрактный класс
B>Поиск так же показывает много других интересных постов по теме.
Конечно не все. Но кнопку поиск использовал. Мой вопрос отличается от поднятых в вышеуказанных топиках, как и в большинстве других топиков на других форумах.
B>Честно говоря никогда не приходилось сталкиватся с такой проблемой выбора. Вроде всегда ясно где что приемнять.
Хм... Вот вы можете попытаться формализовать подход? Я говорю не об универсальной методике, способной раз и навсегда положить конец разговорам на эту тему, а о "сигналах", которые для вас значат: "вот это точно интерфейс".
B>А мне хотелось бы посмотреть на пример (не оторваный от жизни) в котором на первый взгляд одинаково хорошо подходят и абстрактный класс и интерфейс.
Возможно действительно стоило дать пример с самого начала. Пусть это будет "система поиска работы". job.ru, monster.com (не сочтите за джинсу ). Какие, на ваш взгляд, в этой задаче можно выделить классы и какие интерфейсы? И самое главное — почему? (Вопрос застрял где-то между дизайном и Java, если вы понимаете о чем я)
B>Вообще-то у нас есть такие форумы как проектирование и философия.
Вопрос ровно на столько относиться к языку, чтобы его не перемещать в "проектирование" и "философию" .
Re[5]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, boluba, Вы писали:
B>Тут можно спорить. Использование UnsupportedOperationException прямо и подробно описано в документации по Collections Framework.
Баги, которые описаны и задокументированы, перестают быть багами. (с) A.A.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, elinson, Вы писали:
E>Odin iz wariantow (rabotaet daleko ne wsegda): E>Esli imja skoree prilagatelnoe (Serializable, Cloneable) — to Interface, Esli su6estwitelnoe — class.
E>MfG Stas
Спасибо, про этот метод я знаю. Но вот с его применением достаточно часто возникают проблемы (у меня). Используя этот подход, java.lang.Throwable должен был бы быть интерфейсом. А было ли бы это хорошим дизайном?
Re[6]: Проектирование: интерфейс vs абстрактный класс
То что в коллекциях порой выкидывается исключение, что метод не поддерживется?
или то что коллекции практически нельзя расширить или изменить(Josh Bloch)?
или то что в коллекциях нельзя хранить примитивы?
или то что существуют примитивы и объектные ссылки?
или ....?
Я считаю, что в java было сделано много оптимизаций. Может, раньше так и надо было, может без этого java не завоевала те позиции, на которых находится сейчас. Но, в итоге, я вижу достаточной сложный язык. Что бы начать программировать на java, на хорошем уровне, надо обязательно почитать JLS, а если хочешь работать с http — пару десятков книг: первая ссылка в рисунках, на Google: ruby vs java, я понимаю что во многом прикол, но доля правды в этом есть.
И если бы стандартная библиотека устраивала бы людей, не появлялись бы велосипеды:
commons-lang, commons-beanutils, javolution... – велосипеды дополняющий язык (java.lang) хорошими свойствами.
trove4j, commons-collections, commons-primitives, javolution... – велосипеды для коллекций (быстрые коллекции, коллекции для примитивных объектов и т.д.).
Так что у меня, к java не однозначное отношение, кое где хорошее, а кое где и не очень...
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[8]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, Petrovich_Alex, Вы писали:
P_A>Я считаю, что в java было сделано много оптимизаций. Может, раньше так и надо было, может без этого java не завоевала те позиции, на которых находится сейчас. Но, в итоге, я вижу достаточной сложный язык. Что бы начать программировать на java, на хорошем уровне, надо обязательно почитать JLS, а если хочешь работать с http — пару десятков книг: первая ссылка в рисунках, на Google: ruby vs java, я понимаю что во многом прикол, но доля правды в этом есть.
Доля правды есть. С этим я согласен. Но мне интересно было бы взглянуть на список книг по Ruby через 5-7 лет. Думаю, он увеличится существенно.
Тема интересная, но давайте вернемся к проектированию.
Re[3]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, malkolinge, Вы писали:
M>Интерфейс необходимо использовать тогда, когда классы различных иерархий должны иметь возможность единообразной работы.
Как один из вариантов, согласен. Но это относится к созданию дизайна. Меня же больше интересует стадия анализа предметной области (Возможно слово "проектирование" в названии темы было выбрано не совсем удачно).
Ситуация проста. Вы приступаете к новой задаче. Вам никак не обойтись без понимания предметной области (домена, etc.). Вы приступаете к ее нанализу. Вы выбираете, какие сущности и связи предметной области важны для вас с точки зрения решаемой задачи. На этом этапе вы уже начинаете поиск кандидатов в классы и интерфейсы.
я написал: Пусть это будет "система поиска работы". job.ru, monster.com. Какие, на ваш взгляд, в этой задаче можно выделить классы и какие интерфейсы? И самое главное — почему?
Анализируем предметную область: Основных требований два. 1. Работник должен найти работу. 2. Работодатель должен найти исполнителя. Конкретнее:
Работник может:
— опубликовать свое резюме (один ко многим).
— поискать вакансии.
— поискать работодателей.
— сохранять выбранную вакансию (один ко многим).
— сравнить две и более вакансий
Работодатель может:
— опубликовать вакансию (один ко многим).
— поискать работника.
— поискать вакансии (оценить привлекательность своей позиции).
— сравнить две и более вакансий
Например, Работник, Резюме и Вакансия у меня были бы кандидатами в классы. На счет Работодателя не уверен. На счет кандидатов в интерфейсы мысле нет.
Надеюсь, вопрос несколько прояснился . Итак, опираясь на данный пример, какие признаки позволяют выделить кандидатов в интерфейсы и кандидатов в классы?
Re[2]: Проектирование: интерфейс vs абстрактный класс
Здравствуйте, TheOldMan, Вы писали:
TOM>Здравствуйте, boluba, Вы писали:
TOM>1. Если реализация может измениться, всегда используйте интерфейсы. При использовании абстрактных классов реализация может фиксироваться
Если бы всегда заранее можно было сказать, какая часть реализации может измениться, было бы проще.
TOM>2. Интерфейсы применяются для описания дополнительных возможностей (Printable, Serializable, Cloneable) TOM>3. Интерфейсы используются в тех случаях, когда реализация по умолчанию не задана. TOM>4. Абстрактные классы используются при частичном определении реализации по умолчанию TOM>5. Иногда интерфейсы могут использоваться в сочетании с абстрактными классами для создания фиксированного интерфейса, комбинируемого с частичной реализацией. Такая комбинация продоставляет удобства частичной реализации с гибкостью интерфейсов.
Все эти советы относяться к проектированию и реализации, нежели к анализу. Возможно, я не точно сформулировал вопрос. Вот здесь