Какова цель абстрактных классов?

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

14
задан Michael Mrozek 16 June 2010 в 02:38
поделиться

6 ответов

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

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

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

8
ответ дан 1 December 2019 в 13:08
поделиться

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

Связанные вопросы: https://stackoverflow.com/search?q=abstract+vs+interface

4
ответ дан 1 December 2019 в 13:08
поделиться

Для OS X проверьте Jar Bundler:

http://developer.apple.com/mac/library/documentation/Java/Conceptual/Jar_Bundler/Introduction/Introduction.html

-121--3279151-

Самым простым и прагматичным способом, вероятно, является создание оберточной функции вокруг функции даты:

function date_japan() {
  echo date('Y') . '年 ' . date('m') . '月 ' . date('d') . '日';
}
-121--3950517-

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

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

0
ответ дан 1 December 2019 в 13:08
поделиться

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

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

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

Итак, если вы определяете функции и методы, вместо подсказок типов классов, вы просто намекаете на интерфейсы.

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

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 бесплатно!

0
ответ дан 1 December 2019 в 13:08
поделиться

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

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

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

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

3
ответ дан 1 December 2019 в 13:08
поделиться

Вот решение, которое работает:

http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/

-121--2914228-

Сборка AxFoo.dll содержит автоматически созданный класс, полученный из элемента управления System.Windows.Forms.AxHoss. Это довольно просто, он имеет методы, свойства и события, те же, которые вы имеете в .ocx, которые просто вызвать Foo.dll interop библиотеки.

Так что, да, обязательно нужно развернуть обе сборки.

-121--2270202-

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

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

3
ответ дан 1 December 2019 в 13:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: