2010-02-18 2 views
11

Я пытаюсь изучить ООП в PHP, и у меня есть некоторая путаница в отношении интерфейсов и абстрактных классов. Оба они не содержат реализаций, только определений и должны выполняться через их подклассы. Какая часть абстрактных классов четко отличает их от интерфейсов? Кроме того, из-за их очевидного сходства, исходя из каких причин я должен решить использовать один над другим?Какова цель абстрактных классов?

ответ

6

Можно создавать абстрактные классы, которые содержат конкретные элементы, такие как методы или свойства. Вы все равно не можете создать экземпляр абстрактного класса напрямую, но любые созданные подклассы могут извлечь выгоду из реализованных элементов, определенных в абстрактном классе.

Интерфейс, для сравнения, никогда не содержит логики реализации. Для каждого класса реализации не требуется реализация всех членов, определенных в интерфейсе.

С точки зрения того, как я рассматриваю различия, подкласс абстрактного является классом этого типа. например Dog - Animal. Я вижу интерфейс как отношения делает-a. например ICanDisplayImages говорит мне, что класс реализации может отображать изображения, но ничего не говорит о том, что представляет класс.

+0

Если у класса нет реализации, какая цель явно служит его подклассам ...? – SpikETidE

+6

Он стандартизирует, как должна выглядеть реализация. Например, интерфейс адаптера базы данных может определять, какие методы вы должны реализовать. Пользователь может просто заменить один адаптер другим и ожидать, что он будет работать, поскольку интерфейс тот же. –

+0

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

0

Абстрактный класс может содержать реализации метода, если метод не определен как абстрактный. Если метод определен как абстрактный, он не содержит реализацию, но его необходимо реализовать его наследниками. Абстрактный класс не может быть создан, но только унаследован от него, чтобы наследник позволял ему использовать его поведение.

Интерфейс определяет только сигнатуры методов, и любой класс, наследующий от него, должен реализовывать все методы, содержащиеся в интерфейсе.

3

Они оба не содержат реализаций ..

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

В дочернем классе вы можете расширить только один класс (абстрактный класс). Абстрактный класс определяет функциональность, которую вы должны реализовать или просто расширять другими методами в дочерних классах.

Интерфейсы используются для определения поведения класса. Вы можете реализовать более одного интерфейса (и сказать, что мой дочерний класс должен делать это, это и эти тиги!), Но вы можете расширить только один абстрактный класс.

4

abstract класс образует является разновидностью отношения между собой и подкласса, в то время как interface создает следующим образом-а отношения. Таким образом, абстрактные классы гораздо более конкретны, чем интерфейсы, и они могут также содержать конкретные реализации (например, Template methods), тогда как интерфейс определяет контрактный набор методов, которым должен следовать класс реализации. Это гораздо более высокий уровень абстракции, поскольку класс реализации не обязательно должен быть абстрактного класса. Используйте его для стандартизации вашего API.

Похожие вопросы: https://stackoverflow.com/search?q=abstract+vs+interface

3

Помимо философии ООП, описанной в других ответах, я думаю, что основное использование абстрактного класса - это скелет.

Полезно, когда вы разрабатываете приложение или работаете с командой, потому что у вас есть базовый код для работы и расширения, он близок к интерфейсу, но с более сложным рабочим процессом.

0

Обычно интерфейсы используются для определения контрактов, поэтому вы получаете проверку типов. Существует также стиль программирования, называемый «программирование против интерфейсов», что является хорошей идеей. См. :

A. Модули высокого уровня не должны зависеть от модулей низкого уровня. Оба должны зависеть от абстракций.

B. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.»

Таким образом, если вы определили функции и методы, вместо type hinting против классов, вы просто намекают на интерфейсах.

Вот пример. Допустим, вы определяете интерфейс для ввода потоки и потоки и выходные следующим образом:

interface OutputStream{ 
    write($string); // Writes a string to the output. 
    close(); // Closes the output stream. 
} 

interface InputStream{ 
    read($length); // Reads at most $length characters. 
    eof(); // TRUE, if the input stream is empty. 
} 

Теперь вы можете создать copy функцию или метод, который копирует полный выход потока на входе, не имея какой-либо из них:

// 50 is just chosen randomly. 
function copy(InputStream $input, OutputStream $output){ 
    while(!$input->eof()){ 
    $output->write($input->read(50));}} 

Поздравляет, copy реализации в настоящее время работает каждый сочетания потока ввода и вывода, даже без внедрения.

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

Снова пример. Предположим, вы хотите иметь выходные потоки. Вам нужен метод write($s), который записывает строку на вывод, и вы хотите использовать метод writeLine($s), который записывает строку и дополнительную строку новой строки в вывод. Тогда это было бы целесообразно:

abstract class AbstractOutputStream{ 
    public function writeLine($s){ 
    $this->write($s."\n");}} 

Железобетонные выходные потоки в настоящее время может наследоваться от потока абстрактного выхода, реализовать только write и получить writeLine бесплатно!

1

Основное отличие между абстрактным классом и интерфейсом заключается в том, что интерфейс определяет общие поведения, где абстрактный класс является базовым классом для наследования. Другими словами, абстрактный класс определяет некоторый основной набор методов и свойств, которые могут быть разделены подклассами. Рассмотрим класс, который определяет лицензию. Все лицензии имеют идентификационный номер определенного типа и выдаются отдельным лицам или группам. Класс лицензии может быть расширен с помощью класса License License, класса License License и класса Hunting License и т. Д. Основная причина заключается в том, что абстрактная абстрактность класса лицензии будет заключаться в том, что она определяет абстрактную идею лицензии. Существует не такая вещь, как лицензия, поэтому, объявив абстрактную категорию, она не может быть создана.
Интерфейс, с другой стороны, не определяет объект вообще. Он определяет сигнатуры методов. Любой не-абстрактный класс, реализующий интерфейс, должен обеспечить реализацию для всех методов интерфейса. Преимущество здесь заключается в том, что этот метод обеспечивает общий интерфейс для различных типов объектов, например. compareTo() выглядит одинаково при использовании со строками или любым другим объектом.

+0

вы также можете добавить примеры кода, чтобы сделать его более понятным. – nakashu

Смежные вопросы