Абстрактный класс и интерфейс

Bambino

Новичок
Абстрактный класс и интерфейс

Объясните пожалуйста разницу между этими блоками кода, с точки практической точки зрения (вроде выполняют одни и те же функции):

1.
PHP:
abstract class Configurator
{
  abstract function addOption();
  abstract function editOption();
  abstract function removeOption();
}

class ConfigManager extends Configurator {
  function addOption () {
    // код добавления опции
  }
  ...
}
2.
PHP:
interface Configurator
{
  function addOption();
  function editOption();
  function removeOption();
}

class ConfigManager implements Configurator {
  function addOption () {
    // код добавления опции
  }
  ...
}
Это все применительно к некому менеджеру конфигурации, который работает с опциями приложения, хранящимися в БД. Но в будущем хочется иметь возможность хранить опции в XML или текстовых файлах. Насколько я понимаю, я должен предоставить некий интерфейс, который нужно будет реализовывать другими классами, которые будут отвечать за хранение опций в различных ипостасях. Но я порылся в коде классов Zend_Db_* и заметил, что там вовсю используется наследование абстрактных классов. Поэтому я на распутье...
 

Fortop

Новичок
class My implements Traversable, Countable, Serializable
можно

а вот
class My extends MyIterator, MySerializator
нельзя.

Но у абстрактных классов есть преимущество в виде наследования реализации.

Так что смотри сам, что удобнее и нужнее.
 

crocodile2u

http://vbolshov.org.ru
Bambino
Эти вещи нужно прочувствовать. ООП должно стать неотъемлемой частью мышления при разработке, если ты хочешь создавать действительно хорошие ОО-программы.

Мне в свое время очень помогла книга Alan Shalloway: Design Patterns Explained. Она написана не столь академическим языком, как GoF, (которого я на тот момент уже успел прочитать) и у меня в какой-то момент мозги прям как-то повернулись, я стал совершенно по-другому смотреть на инкапсуляцию, наследование, полиморфизм.

Уже после этого я перечитал GoF и вот из второго прочтения вынес гораздо больше, чем из первого.
 

HraKK

Мудак
Команда форума
Надо понимать что интерфейс служит для того чтоб гарантировать наличие определенных методов у класса, а абстрактный класс служит чтоб вынести реализацию каких-то общих методов.
 

Krishna

Продался Java
Не забываем так же, что у абстрактного метода, в отличие от интерфейса, могут быть абсолютно конкретные (ну собсно только такие и могут) свойства :)

А вообще это очень распространённый вопрос на собеседованиях, служащий в качестве одной из лакмусовых бумажек на понимание ООП. Сам такой задавал. И мне тоже такой задавали :)
 

Bambino

Новичок
Автор оригинала: HraKK
Надо понимать что интерфейс служит для того чтоб гарантировать наличие определенных методов у класса, а абстрактный класс служит чтоб вынести реализацию каких-то общих методов.
Это ясно.
А если применительно к примерам, которые я привел? Ведь в обоих случаях предок представляет собой просто описание "интерфейса", просто второй случай есть именно интерфейс. В обоих случаях потомок реализует интерфейс. Оба потомка могут быть опять же наследуемы, т.е. налицо вынесение реализации общих методов. Не очень понятна разница. Или просто может просто эти примеры в данном случае не несут практического смысла?
 

Gas

может по одной?
Bambino
для твоего случая (классы адаптеры под xml, файлы, базу) я бы выбрал абстрактный класс в качестве парента.
Но я не считаю себя гуру ооп, по-этому имхо )
 

Adelf

Administrator
Команда форума
Это все довольно тонко... Сам я тоже не всегда понимаю. Попробую свою точку зрения объяснить.
class ConfigManager extends Configurator - это значит, что класс ConfigManager является конфигуратором. Это его основное предназначение. Его место в программе четко определено :)

class ConfigManager implements Configurator - это значит, что класс ConfigManager может вести себя так, как конфигуратор. А основным занятием его может быть совсем другое, но это и неважно :)

Вот реализуешь ты свои классы ConfigManager... через год захочешь добавить метод removeAllOptions. В абстрактный вставишь реализацию - и появится у всех. С интерфейсом так не получится.
Все эти вещи надо научиться чувствовать. На словах сложно объяснять.
 

Bambino

Новичок
Это можно понять, когда абстрактный класс реализует какие-то общие методы. Но в данном случае общих методов вроде как и нет. Если какой-то метод addOption в случае с БД будет использовать SQL-запрос, то в случае текстового файла будет будет какая-то работа с файлом.

Вот ты говоришь "захочешь добавить метод". Ну добавлю я его и что? Ведь для конфигураторов, работающих с разными "БД" мне нужна будет своя реализация этого removeAllOptions, т.е. придется писать для обоих (или более) классов.

P.S. Кстати, заметили ли вы, что все методы абстрактного класса тоже абстрактные? Т.е. никаких реализаций, а чистое описание "интерфейса". И вообще такое описание класса, в принципе, имеет смысл?
 

Fortop

Новичок
работающих с разными "БД" мне нужна будет своя реализация этого removeAllOptions, т.е. придется писать для обоих (или более) классов.
Кстати, почему?
Как раз этот метод может быть общим без изменений.
 

Adelf

Administrator
Команда форума
Fortop
Ну с данными методами - не может. А вот например какой-нибудь replaceOption - вполне(add or edit т.е.).
 

Adelf

Administrator
Команда форума
PHP:
abstract function addOption();
abstract function editOption();
abstract function removeOption();
Удали все опции используя только эти методы .
Напомню - о реализации мы из этого класса ничего не знаем.
 
Сверху