Вопросы и ответы на собеседованиях PHP программистов. Часть 2 — Блог Виктора Зинченко
1. Чем отличается аутентификация от авторизации?
Аутентификация (authentication) — процедура проверки подлинности.
Например: проверка подлинности пользователя путем сравнения введенного пароля с паролем в базе данных.
Авторизация (authorization) — предоставление и проверка прав пользователя на выполнение определенных действий.
Как это происходит, например, на сайте? После ввода логина и пароля пользователь проходит процедуру аутентификации, т.е. проверку введенных данных с данными, которые он оставил при регистрации.
При переходе, например, в административную часть сайта (админку) система проверяет наличие прав доступа у текущего пользователя (например, это может быть роль “admin”).
2. Что такое интерфейс и абстрактный класс? Зачем они нужны?
По сути, абстрактные классы и интерфейсы — это чертежи.
Интерфейсы могут содержать только абстрактные методы.
Абстрактный метод — метод класса, реализация для которого отсутствует.
В абстрактном классе можно объявлять и использовать переменные и методы (не только абстрактные).
Объект создать ни от абстрактного класса, ни от интерфейса не получится, их можно только наследовать. Для наследования абстрактного класса используется ключевое слово extends, для наследования интерфейса используется ключевое слово implements. Дочерний класс напрямую может наследовать только один класс (не важно, абстрактный или нет), интерфейсов может наследовать несколько (implements Interface1, Interface2, Interface3, ….). Абстрактные методы обязательно должны быть переопределены в наследующем классе (если только он не является абстрактным в свою очередь).
Зачем?
Интерфейсы позволяют гарантировать, что какой-либо используемый объект (класс) реализует необходимый набор методов. Например: если разработчиков несколько, то для того, что б контролировать код, который еще не написан (и будет написан разными людьми) создается интерфейс с перечнем функций, которые должен реализовывать класс, их названиями, параметрами и возвращаемыми значениями.
В абстрактном классе реализуют методы общие для потомков. К примеру: для экземпляров классов Triangle и Rectangle (унаследованных от абстрактного класса Figure, содержащего реализацию универсального метода draw) мы можем применять метод draw не задумываясь о его реализации, т.к. он реализован в родительском классе Figure.
3. Нормализация в БД.
Нормализация БД — сложная и обширная тема. Вряд ли я смогу обойтись несколькими абзацами и хорошо это объяснить. Потому, просто оставлю это здесь: ссылка 1, ссылка 2.
4. Что такое магические методы в PHP?
Любой встроенный метод в php, который начинается с __ называется магическим. Их особенность состоит в том, что они могут вызываться при совершении какого-то действия автоматически и без ведома программиста.
Это методы:
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(),__invoke(), __set_state(), __clone(), __debugInfo()
Лучше всего о них написано в официальном руководстве.
5. Какие паттерны проектирования знаете?
Смысл в том, что паттерны нечасто используются в рядовых задачах в сфере программирования. Бывает и так, что разработчик использует готовые решения и не всегда задумывается о паттернах, которые используются.
К счастью, я наткнулся на эту статью. Здесь есть небольшая шпаргалка по паттернам (в конце статьи есть pdf документ). Рекомендую к ознакомлению!
http://habrahabr.ru/post/210288/
6. Какие методы http Вы знаете?
Заучив ответ на этот вопрос Вы вряд ли получите целостное понимание работы http. Потому, рекомендую ознакомиться с принципами и структурой этого протокола.
Но предупреждаю: не вдавайтесь в крайности — не стоит зубрить все до каждой буквы наизусть, ведь вещи, которые мы применяем редко, забываются. Вас поймут на собеседовании, если Вы не будете знать всех мелочей, но понимать основные принципы работы.
Очень часто бывает, что кандидат обладает достаточными знаниями для работы, но не может правильно сформулировать ответы на вопросы на собеседовании.
P.S. Если я где-то допустил неточность — пишите в комментарии, спасибо!
Поделитесь с друзьями или сохраните себе
Почему в PHP есть абстрактные классы, если вы можете использовать интерфейс и черты?
Я думаю, что есть философское различие в том, как и когда их использовать.
Вы сказали:
- абстрактные классы: «все, что использует меня, будет использовать эти методы и атрибуты»
- интерфейсы: «все, что использует меня, должно иметь эти методы и атрибуты»
- черты: «все, что использует меня , также будет иметь эти методы и атрибуты».
Если вы сосредоточены на своих собственных формулировках, это имеет смысл.
Абстрактные классы в действительности определяют абстрактные вещи, например, «Транспортное средство» является абстрактным до тех пор, пока оно не материализуется в форме автомобиля или велосипеда. Ни интерфейс не определяет это, ни черты.
Интерфейсы дополняют функциональность наследования классов, когда класс наследуется от нескольких классов (только некоторые языки обеспечивают множественное наследование, например C/C++). Интерфейсы, как следует из названий, ориентированы на ИНТЕРФЕЙС, а не на реализацию метода интерфейса в классе, который его реализует. Это делает классы
Черты имеют реализацию / функциональность, которая не привязана к конкретным классам. Вместо этого ее можно найти в разных классах. Это как ген в генетике, который остается немым у родителей и появляется только у определенных детей. Или быть кратким избирательным наследованием, но не привязанным к одному классу. Так что это обеспечивает намного лучшее
Edit Interface + Trait! = Abstract Class, потому что при использовании наследования selective
как вы выбираете конкретную черту для использования и при использовании Abstract Class
наследование является обязательным или продиктовано родительским классом, у вас нет свободы!
PHP в именовании про абстрактные классы и интерфейсы
должен ли абстрактный класс всегда иметь префикс Abstract
и далее Interface
(когда это интерфейс)? Существует ли стандартное соглашение об именах, подобное PSR-0 для структуры папок / пространств имен, но для классов?
5 ответов
для этого нет соглашения; особенно в PHP. Все это может быть организовано так, как вы хотите.
с дополнениями от пространства имен в PHP 5.3, я не вижу необходимости добавлять Abstract
или Interface
префиксы/суффиксы для названия класса.
просто назовите вещи, как они есть!
хотя нет никакого соглашения, я думаю, что это хорошая практика использования Abstract
префикс и Interface
суффикс для соответствующих компонентов. Это помогает лучше понять код с первого взгляда, ИМО.
соглашения — это то, что вы видите: сам язык не заставляет никаких соглашений, кроме тех, которые делают парсер способным читать ваш код. В принципе, вы должны иметь соглашения, созданные самостоятельно для конкретного проекта или, лучше, для всех ваших проектов. Однако работа в командах разных людей может привести к тому, что конвенции не будут соблюдаться, это действительно зависит от программистов.
из моего опыта я бы предложил следующее: «проектирование по контракту «. Назовите свои контракты (интерфейсы), как вы назвали бы свой класс реализации, а затем дайте своей реализации более конкретное имя (или резервный вариант MyContractNameImpl, известный в основном из Java, я думаю). Кроме того, многие современные IDE знают, является ли ваш класс интерфейсом или абстрактным, поэтому нет необходимости помещать это в его имя. Я также нахожу контракты с именем «IMyContract » не очень хорошими по тем же причинам.
1
автор: themarketka
именование абстрактных классов и интерфейса с помощью:
- Аннотация*
- интерфейс
будет держать вашу кодовую базу чистой, приятной и очевидной для вашей команды, каковы прототипы, каковы контракты и каковы конкретные реализации.
Соглашения об именах здесь, чтобы увеличить нашу производительность в любых обстоятельствах, поэтому «имя, как вам нравится » далека от хорошей идеи.
даже если группа FIG не предложите соглашение об именах для абстрактных классов и интерфейсов — если вы изучите основные проекты PHP с открытым исходным кодом, вы увидите, что почти все они используют это соглашение.
1
автор: Nikola Svitlica
проект PHP-FIG действительно предлагает соглашение об именах через соглашение об именах PSR » ByLaw «https://www.php-fig.org/bylaws/psr-naming-conventions/
в нем говорится:
интерфейсы должны быть суффиксами интерфейса: например
PsrFooBarInterface
абстрактные классы должны иметь префикс Abstract: например
PsrFooAbstractBar
черты должны быть суффиксами по признакам: например,
PsrFooBarTrait
эти соглашения обычно соблюдаются в пакетах
Малоизвестные «особенности» OO-модели PHP — CoderLessons.
comПодавляющее большинство современных приложений, написанных на PHP, являются объектно-ориентированными, и в целом основные концепции ООП довольно хорошо понятны разработчикам PHP. Эта статья расширяет границы вашего понимания и показывает вам некоторые хитрости или потенциальные ловушки в зависимости от вашей перспективы ООП в PHP.
Наследование для интерфейсов и признаков
Начнем с привычной территории: интерфейсы. Интерфейс в PHP позволяет нам определять контракт, который должен реализовать любой объект, реализующий этот интерфейс. Но знаете ли вы, что интерфейсы могут также наследовать другие интерфейсы и что родительский или дочерний интерфейс может быть реализован классом?
Рассмотрим этот код, который определяет интерфейс, другой, расширяющий его, и класс, реализующий дочерний интерфейс:
<?php interface Reversible { function reverse($target); } interface Recursible extends Reversible { function recurse($target); } class Tricks implements Recursible { public function recurse($target) {
Я определил интерфейс с именем Reversible
и еще один Recursible
именем Recursible
, расширяющий его. Когда я реализую Recursible
в классе Tricks
, должны присутствовать как метод Recursible
recurse()
из интерфейса Recursible
и метод reverse()
из интерфейса Reversible
.
Это полезный метод для применения, когда интерфейс будет содержать методы, которые используются в одном наборе классов, но другой набор классов нуждается в них и в дополнительном наборе методов. Вы можете создать составной интерфейс, как показано здесь, а не реализовывать два интерфейса.
Черты предлагают аналогичную модель. Если у вас еще не было возможности использовать признаки, они выглядят как классы и могут содержать полные определения методов, которые можно применять к любому классу (классам) в вашем приложении, без необходимости наследования из общего расположения. Нас часто учат, что лучше перемещать код в общий родительский класс, чем копировать и вставлять между классами, но иногда классы не связаны, и наследование ложно. Черты — отличная особенность, потому что они позволяют нам повторно использовать код, даже если объекты недостаточно похожи, чтобы оправдать наследование.
Давайте посмотрим на пример простой черты. (Предупреждение: схема именования zany из предыдущего примера все еще находится в действии.)
<?php trait Reversible { public function reverse($target) { return array_reverse($target); } }
Синтаксис признаков выглядит очень похоже на класс, и действительно, признаки могут содержать как свойства, так и методы, включая абстрактные методы. Затем они применяются в классе, который вводит в него признак с помощью ключевого слова use
… или их также можно применить к признаку, как мы видим здесь:
<?php trait RecursivelyReversible { use Reversible; public function reverseRecursively($target) { foreach($target as $key => $item) { if(is_array($item)) { $target[$key] = $this->reverseRecursively($item); } } return $this->reverse($target); } }
Теперь у нас есть черта, которая использует другую черту и добавляет собственный метод. Этот метод вызывает метод первой черты. На этом этапе мы можем применить черту к классу, и поскольку черты содержат функцию, которую я хочу проиллюстрировать здесь, класс не содержит ничего другого.
<?php class Mirror { use RecursivelyReversible; } $array = [1, "green", "blue", ["cat", "sat", "mat", [0,1,2]]]; $reflect = new Mirror(); print_r($reflect->reverseRecursively($array));
Если вы запустите код, то увидите, что не только верхний уровень массива меняется на противоположный, но и PHP также детализирует и инвертирует все дочерние элементы.
Насколько частной является частная собственность?
То есть вы подумали, что частная собственность доступна только из текущего объекта? Не совсем верно! На самом деле ограничение касается только имени класса, поэтому объекты одного класса могут обращаться к закрытым свойствам и методам друг друга. Чтобы проиллюстрировать это, я создал класс с закрытым свойством и открытым методом, который принимает экземпляр того же класса объекта в качестве аргумента:
<?php class Storage { private $things = []; public function add($item) { $this->things[] = $item; } public function evaluate(Storage $container) { return $container->things; } } $bucket = new Storage(); $bucket->add("phone"); $bucket->add("biscuits"); $bucket->add("handcream"); $basket = new Storage(); print_r($basket->evaluate($bucket));
Вы можете подумать, что $basket
не будет иметь доступа к частным данным $bucket
, но на самом деле приведенный выше код работает просто отлично! Спрашивать, является ли это поведение гочей или особенностью, все равно, что спрашивать, является ли растение цветком или сорняком; это зависит от вашего намерения и перспективы.
Как выглядит абстрактный класс?
Абстрактный класс обычно считается неполным классом; мы определяем только частичную функциональность и используем ключевое слово abstract
чтобы остановить попытки создания чего-либо.
<?php class Incomplete { abstract public function notFinished(); }
Если вы попытаетесь создать экземпляр Incomplete
, вы увидите следующую ошибку:
Фатальная ошибка PHP: класс Incomplete содержит 1 абстрактный метод и поэтому должен быть объявлен абстрактным или реализовать остальные методы (Incomplete :: notFinished) в / home / lorna / sitepoint / oop-features / incomplete.php в строке 5
Сообщение не требует пояснений, но теперь рассмотрим другой класс:
<?php abstract class PerfectlyGood { public function doCoolStuff() {
Это совершенно допустимый класс, кроме abstract
ключевого слова. На самом деле, вы можете пометить любой класс как абстрактный, если хотите. Другие классы могут расширять его, но сам по себе он не может быть создан. Это может быть полезным устройством для разработчиков библиотек, которые хотят, чтобы разработчики расширяли свои классы, а не использовали их напрямую. Именно поэтому Zend Framework имеет богатую традицию абстрактных классов.
Тип подсказки не автозагрузка
Мы используем подсказки типов, чтобы гарантировать, что входящий параметр метода удовлетворяет определенным требованиям, давая имя класса или интерфейса, которым он должен быть (или должен быть связан). Однако PHP не вызывает автозагрузчик, если класс или интерфейс, указанный в подсказке типа, еще не объявлен; мы просто увидим ошибку объявления отсутствующего класса.
<?php namespace MyNamespace; class MyException extends Exception { } class MyClass { public function doSomething() { throw new MyException("you fool!"); } } try { $myclass = new MyClass(); $myclass->doSomething(); echo "that went well"; } catch (Exception $e) { echo "uh oh. .. " . $e->getMessage(); }
Имя класса в предложении catch на самом деле является подсказкой типа, но поскольку мы не указали, что класс Exception
находится в пространстве имен верхнего уровня, PHP считает, что мы имеем в виду MyNamespaceException
которого не существует. Отсутствующий класс не вызывает ошибку, но наше исключение теперь пропускает предложение catch
. Вы можете ожидать, что мы увидим отсутствующее сообщение MyNamespaceException
, но вместо этого мы получим невыразимо уродливую ошибку «Uncaught Exception»:
Неустранимая ошибка: необработанное исключение «MyNameSpaceMyException» с сообщением "ты дурак!" в / home / lorna / sitepoint / OOP-функции / namespaced_typehints.php: 11
Такое поведение имеет смысл, если вы об этом думаете — если что-то, названное в подсказке типа, еще не загружено, то по определению входящий параметр не может ему соответствовать. Я должен был сделать эту ошибку сам, прежде чем я действительно думал об этом, и это просто опечатка! Если вы поймаете Exception
а не только Exception
, это Exception
, как я планировал.
И наконец
Предложение finally
— это функция, о которой стоит знать, недавно появившаяся в PHP 5.5. Если вы использовали другие языки программирования с исключениями, возможно, вы уже видели эту конструкцию раньше. Есть только один блок try
, мы можем иметь столько блоков catch
сколько пожелаем, и из этой версии PHP мы также можем добавить finally
.
Вот снова предыдущий пример кода, finally
добавленный:
<?php namespace MyNameSpace; class MyException extends Exception { } class MyClass { public function doSomething() { throw new MyException("you fool!"); } } try { $myclass = new MyClass(); $myclass->doSomething(); echo "that went well"; } catch (Exception $e) { echo "uh oh ... " . $e->getMessage(); } finally { echo "move along, nothing to see here"; }
Предложение finally
всегда будет происходить независимо от того, достигли ли мы конца блока try
, вошли ли какие-либо из блоков catch
или есть ли еще неучтенные исключения на пути. В этом примере вывод из блока finally
действительно появляется перед ошибкой об исключении uncaught, потому что он не является uncaught, пока мы не завершим раздел try
/ catch
/ finally
.
Вывод
Конечно, некоторые из приведенных здесь примеров являются надуманными, и, надеюсь, вы не будете сталкиваться с ними каждый день, но я думаю, что стоит знать, как выглядят крайние случаи, чтобы вы могли правильно проектировать и создавать системы. Понимание строительных блоков, безусловно, может помочь нам выполнить свою работу и быстро отладить проблемы, и мне нравится делиться идеями, чтобы сделать это проще!
Что ты нашел в PHP? Пожалуйста, поделитесь с остальными в разделе комментариев.
Изображение через Fotolia
Абстрактный класс
1.3. Примеры. C#
Модификатор abstract (аннотация) указывает, что класс может быть использован только как базовый класс при наследовании. абстрактные классы могут содержать абстрактные методы и методы доступа. создавать экземпляры абстрактного класса-это не вызов конструктора, но экземпляр абстрактного класса создается неявно при создании экземпляра производного класса. определенный неабстрактный класс, производный от абстрактного, должен содержать фактические реализации всех наследуемых абстрактных методов и методов доступа, чтобы указать на отсутствие реализации метода или свойства, используйте модификатор abstract (аннотация) в объявлении метода или свойства. абстрактный метод неявно виртуальный метод. объявления аннотация участники допускаются только в абстрактных классов и интерфейсов. потому что объявление абстрактного метода не предоставляет фактической реализации, тело метода отсутствует, в объявлении метода просто заканчивается точкой с запятой, аналогично объявлению прототипы:
Осуществления предложен способ переопределения override (переопределить), который является членом неабстрактный класс.
Использование статических или виртуальных модификаторов в объявлении абстрактного метода или свойства не является допустимым. абстрактных свойств аналогично абстрактным методам, за исключением отличий в синтаксисе объявления и звонки. абстрактное унаследованное свойство может быть переопределено в производном классе, в том числе в собственность декларацию, в которой используется модификатор override.
Абстрактного класса должны предоставить реализацию для всех членов интерфейс. абстрактный класс, который реализует интерфейс может отображать методов интерфейса абстрактные методы.
Абстрактный класс с модификатором sealed (запечатанный) не может быть использован в качестве модификатора abstract (аннотация) и sealed (запечатанный) имеют взаимоисключающие значения. модификатор sealed (запечатанный) запрещает наследование класса, в то время как модификатор abstract (аннотация) показывает, что класс должен быть унаследован.
Абстрактные классы в Python | OTUS
В прошлый раз, рассматривая принципы работы со слотами в классах, мы столкнулись с проблемой множественного наследования. Суть проблемы заключалась в том, что если у двух классов определён атрибут __slots__, то создать от них общий дочерний класс не получится.
class BaseA: __slots__ = ('a',) class BaseB: __slots__ = ('b',) >>> class Child(BaseA, BaseB): __slots__ = () Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: multiple bases have instance lay-out conflict
Можно, конечно, не указывать слоты в родительских классах и заполнить их только в дочернем, но это частный случай. Что же делать, если слоты нужны во всех трёх классах?
Как раз для таких (хотя и не только) случаев в ООП есть принцип абстрагирования. Правда, в Python на уровне абстракции не реализованы, но в стандартную библиотеку входит модуль abc — Abstract Base Classes.
Абстрактный класс сам по себе нельзя инстанцировать — в нём определяется, какие методы и свойства нужно будет переопределить в дочерних классах.
from abc import ABC, abstractmethod, abstractproperty class AbstractBase(ABC): @abstractmethod def foo(self): pass @abstractproperty def baz(self): pass >>> AbstractBase() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class AbstractBase with abstract methods baz, foo class Base(AbstractBase): def foo(self): print('foo') @property def baz(self): return 'baz' >>> base = Base() >>> base.foo() foo >>> base.baz 'baz'
Благодаря использованию абстрактных классов мы можем проконтролировать, что все дочерние классы имеют одинаковый интерфейс. Проще всего это понять на примере.
class SerialPort(ABC): @abstractmethod def read(self): pass @abstractmethod def write(self): pass
Мы создали абстрактный класс SerialPort. Теперь, наследуя от него разные реализации (COM, USB, USB-C), мы не будем обязаны реализовать 2 базовых метода. Это будет гарантировать, что реализации всех конкретных классов можно использовать одинаково, не заботясь о том, какой именно последовательный порт используется.
class COM(SerialPort): pass >>> com = COM() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class COM with abstract methods read, write class COM(SerialPort): def read(self): return "" def write(self): pass >>> com = COM() >>> com.read() ''
Рассмотрим множественное наследование от абстрактных классов:
class Charger(ABC): @abstractmethod def charge(self): pass class USB(SerialPort, Charger): def read(self): return "" def write(self): pass >>> usb = USB() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't instantiate abstract class USB with abstract methods charge
Ага, класс USB должен обязательно иметь имплементацию метода charge, поскольку это задекларировано в родительском классе Charger:
class USB(SerialPort, Charger): def read(self): return "" def write(self): pass def charge(self): print('Charging') >>> usb = USB() >>> usb.charge() Charging
Возвращаясь к проблеме со __slots__, решение через абстрактные классы выглядит примерно так:
class AbstractA(ABC): __slots__ = () class AbstractB(ABC): __slots__ = () class BaseA(AbstractA): __slots__ = ('a',) class BaseB(AbstractB): __slots__ = ('b',) class Child(AbstractA, AbstractB): __slots__ = ('a', 'b') c = Child()
То есть мы вместо того, чтобы наследоваться от классов с конкретной реализацией (BaseA, BaseB), наследуемся от абстрактных классов. Таким образом, мы, гарантируя совместимость интерфейсов, определяем независимые слоты для каждого из классов.
Абстрактный класс в Python | Как работают абстрактные классы в Python?
Обзор абстрактного класса в Python
Абстрактные классы — это классы, которые объявлены, но не содержат реализаций. Это может быть только унаследовано. Абстрактные классы работают как шаблон для подклассов. Абстрактные классы не могут быть созданы и требуют подклассов для обеспечения реализации абстрактных методов. Для обеспечения реализации абстрактных методов, определенных в абстрактных классах, нужны подклассы. Абстрактные классы содержат один или несколько абстрактных методов. Абстрактные методы — это методы, которые объявлены без каких-либо реализаций. Мы не можем напрямую создать объект абстрактного класса, но мы можем наследовать базовый класс, а затем создать объект. В этой теме мы собираемся узнать об абстрактном классе в Python.
Как абстрактный класс, так и конкретный класс могут содержаться в абстрактном классе. Используя абстрактный класс, мы можем определить обобщенную структуру методов без предоставления полной реализации каждого метода. Абстрактные методы, которые определены в абстрактном классе, обычно не имеют тела, но возможно иметь абстрактные методы с реализациями в абстрактном классе, и если какой-либо подкласс становится производным от такого абстрактного класса, необходимо предоставить реализацию для таких методов, Если какой-либо абстрактный метод не реализован производным классом, он выдаст ошибку. Абстрактный объект класса не может быть создан напрямую, но когда мы используем этот абстрактный класс для предоставления определенных функций базовому классу или дочернему классу, он может сделать это, создав объект базового класса.
Важность абстрактных классов
1. Он обеспечивает функциональность по умолчанию базовых классов.
2. Он определяет общий API для набора подклассов, полезен, когда третье лицо предоставляет плагины в приложении.
3. Полезным в большом коде было запоминание многих классов, это сложно.
Синтаксис
From abc import ABC
Class Educba(ABC):
Чтобы рассматривать любой класс как абстрактный класс, класс должен наследовать метакласс ABC от встроенного abc-модуля python. Модуль abc импортирует метакласс ABC.
Абстрактные методы в Python
Абстрактные методы — это методы, которые объявлены без каких-либо реализаций.
Синтаксис
from abc import ABC, abstract method
Class Educba(ABC):
@abstractmethod
def mymethod(self):
#empty body
pass
Чтобы определить абстрактные методы в абстрактном классе, метод должен быть украшен ключевым словом @abstractmethod decorator. Декоратор @abstractmethod должен быть импортирован из встроенной библиотеки python abc.
Как абстрактные классы работают в Python?
Python не имеет абстрактных классов по умолчанию, но у него есть модуль или библиотека, которые образуют основу для определения абстрактных базовых классов (ABC), и это имя модуля называется ABC. Он помечает метод базового класса как абстрактный базовый класс, а затем создает конкретные классы как реализации абстрактной базы. Метод превращается в абстрактный метод с помощью ключевого слова decorator, называемого @abstractmethod.
Модуль ABC используется для создания абстрактных классов, @ abstractmethod — декоратор, используемый для объявления абстрактного метода. Модуль ABC устанавливает договор между базовым классом и конкретным классом.
Модуль abc обеспечивает основу для определения абстрактных базовых классов (ABC) в Python. Модуль коллекций имеет несколько конкретных классов, которые являются производными от ABC, и их можно разделить дальше. Помимо всего этого, модуль коллекций также содержит некоторые ABC, которые можно использовать для проверки того, предоставляет ли класс или экземпляр конкретный интерфейс или нет.
Этот модуль предоставляет следующий класс:
класс abc.ABCMeta
Метакласс используется для определения абстрактных базовых классов (ABC)
Мы используем метакласс для создания абстрактного базового класса.
from abc import ABCMeta
class C:
__metaclass__ = ABCMeta
MyABC.register(tuple)
assert issubclass(tuple, C)
assert isinstance((), C)
пример
# importing the ABC module
from abc import ABC, abstractmethod
class Shape(ABC):
def common(self):
print("This is a concrete method")
@abstractmethod # decorator
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Square(Shape):
def __init__(self, side):
self.__side=side
def area(self):
return self.__side*self.__side
def perimeter(self):
return 4*self.__side
class Rectangle(Shape):
def __init__(self, length, breath):
self.__length=length
self.__breath=breath
def area(self):
return self.__length*self.__breath
def perimeter(self):
return 2*(self.__length+self.__breath)
S1=Square(4)
print(S1.common())
print(S1.area())
print(S1.perimeter())
R1=Rectangle(2, 4)
print(R1.common())
print(R1.area())
print(R1.perimeter())
Выход получен
Это конкретный метод
16
16
Это конкретный метод
8
12
В приведенном выше примере класс Abstract — это Shape, который содержит один конкретный метод, называемый common, и два абстрактных метода, называемых area и perimeter. Есть два дочерних класса Square и Rectangle, которые наследуют абстрактный класс Shape и реализуют абстрактный метод.
Реализация через подклассы:
import abc
class Shape:
def area(self):
pass
class Square(Shape):
def area(self):
print("Square is a child class")
print( issubclass(Square, Shape))
print( isinstance(Square(), Shape))
Абстрактные свойства
Абстрактные классы содержат абстрактные свойства наряду с абстрактными методами, определенными @abstractproperty.
Теперь мы можем использовать property, property.getter (), property.setter () и property.deleter () с абстрактными классами.
Синтаксис
class class_name(ABC):
@property
@abstractmethod
Def method(self):
Это определяет свойство только для чтения.
class Class_name:
__metaclass__ = ABCMeta
def getx(self): ...
def setx(self, value): ...
x = abstractproperty(getx, setx)
Python 2
class C(ABC):
@abstractproperty
def my_abstract_property(self):
Python 3.3
class C(ABC):
@property
@abstractmethod
def my_abstract_property(self):
import abc
from abc import ABC, abstractmethod
class Shape(ABC):
@abc.abstractproperty
def area(self):
return "Shape class"
class Square(parent):
@property
def area(self):
return "Square class"
try:
s1 =Shape()
print( s1.area)
except for Exception as err:
print (err)
s1 = Square()
print (s1.area)
Выход:
Не удалось создать экземпляр абстрактного класса Shape с областью абстрактного метода
Квадратный класс
Вывод
Наконец, я пришел к выводу, что абстрактный класс — это способ обеспечить определенный уровень качества кода, поскольку он обеспечивает соблюдение определенных стандартов и может уменьшить объем дублирующегося кода, который мы пишем. Он устанавливает связь между базовым классом и конкретным классом. Это обеспечивает простую реализацию кода. Он определяет обобщенную структуру методов без ее полной реализации. Это облегчает жизнь программиста, абстрагируя фоновый процесс и фокусируя его только на важных моментах. Это делает исследование и понимание намного быстрее благодаря пониманию общей и простой структуры классов в коде.
Рекомендуемые статьи
Это руководство по абстрактному классу в Python. Здесь мы обсуждаем, как абстрактные классы работают в Python с важностью и методами с соответствующими примерами. Вы также можете взглянуть на следующие статьи, чтобы узнать больше —
- Файловые операции Python
- Инкапсуляция в Python
- Петли в Python
- Конструктор в Python
- Наборы Python
- Введение в абстрактный класс в PHP
php — Интерфейс или абстрактный класс: какой использовать?
Также я хотел бы добавить сюда, что тот факт, что любой другой объектно-ориентированный язык имеет какие-то интерфейсы и абстракцию, не означает, что они имеют то же значение и цель, что и в PHP. Использование абстракции / интерфейсов немного отличается, в то время как интерфейсы в PHP фактически не имеют реальной функции. Они просто используются по причинам, связанным с семантикой и схемой. Дело в том, чтобы проект был как можно более гибким, расширяемым и безопасным для будущих расширений, независимо от того, будет ли у разработчика в дальнейшем совершенно другой план использования или нет.
Если ваш английский не является родным, вы можете узнать, что такое абстракция и интерфейсы на самом деле. И синонимы тоже ищите.
И это может помочь вам в качестве метафоры:
ИНТЕРФЕЙС
Допустим, вы испекли новый сорт пирога с клубникой и составили рецепт с описанием ингредиентов и этапов. Только вы знаете, почему он такой вкусный и нравится вашим гостям. Затем вы решаете опубликовать свой рецепт, чтобы другие люди тоже могли попробовать этот торт.
Дело здесь
— чтобы было правильно
— осторожно
— для предотвращения вещей, которые могут испортиться (например, слишком много клубники или чего-то еще)
— упростить для тех, кто попробует
— сказать вам, сколько времени нужно делать (например, помешивать)
— чтобы сказать, что вы МОЖЕТЕ делать, но НЕ ИМЕЕТЕ, на номер
Именно ЭТО и описывает интерфейсы.Это руководство, набор инструкций, в которых соблюдается содержание рецепта. То же самое, как если бы вы создали проект на PHP и хотите предоставить код на GitHub, вместе со своими товарищами или чем-то еще. Интерфейс — это то, что люди могут делать, а вам — нет. Правила, которые его держат — если вы нарушите одно, вся конструкция будет сломана.
АБСТРАКЦИЯ
Продолжая эту метафору … представьте, что на этот раз вы гость, который ест этот торт. Тогда вы пробуете торт по рецепту.Но вы хотите добавить новые ингредиенты или изменить / пропустить шаги, описанные в рецепте. Итак, что будет дальше? Придумайте другой вариант этого торта. На этот раз с черными ягодами, а не с соломенными ягодами, а с добавлением ванильного крема … вкусно.
Это то, что можно считать продолжением оригинального торта. Вы в основном делаете его абстракцию, создавая новый рецепт, потому что он немного отличается. В нем есть несколько новых шагов и другие ингредиенты. Однако в версии с черными ягодами есть некоторые части, которые вы переняли из оригинала — это базовые шаги, которые должны быть у каждого вида этого торта.Как ингредиенты, как молоко — это то, что есть в каждом производном классе.
Теперь вы хотите поменять ингредиенты и этапы, и они ДОЛЖНЫ быть определены в новой версии этого торта. Это абстрактных методов , которые должны быть определены для нового торта, потому что в торте должен быть фрукт, но какие? Итак, на этот раз вы возьмете черные ягоды. Сделанный.
Итак, вы расширили торт, следовали интерфейсу и извлекли из него шаги и ингредиенты.
Практическая демонстрация интерфейсов и абстрактных классов в PHP | Кейси МакМаллен
Абстрактный класс — это класс, который не только может определять требуемые методы для конкретных классов, но также может обеспечивать реализацию этих методов. Чтобы использовать абстрактный класс, конкретный класс должен расширять абстрактный класс, который затем делает все методы, определенные в абстрактном, доступными внутри конкретного класса.
Чтобы проиллюстрировать это, давайте начнем с изучения нашего абстрактного класса Data_Access
.В нашем примере кода я создал файл с именем data_access.php
. В нем есть две функции: dbConnect
и getResultSetArray
.
На изображении 1 ниже вы можете видеть, что мы определяем Data_Access
как «абстрактный класс» в третьей строке. Это навязывает идею о том, что это абстрактный класс, и поэтому не может быть создан как как отдельный класс. может быть расширен только . Это правило абстрактных классов, которое гарантирует, что оно рассматривается как абстрактное.
Если бы мы попытались создать экземпляр класса Data_Access
как автономный объект:
$ cDataAccess = new Data_Access;
Это вызовет следующую ошибку:
Неустранимая ошибка PHP: Неперехваченная ошибка: невозможно создать экземпляр абстрактного класса Data_Access ...Изображение 1: Data_Access :: dbConnect
Изображение 1 выше показывает функцию dbConnect
в Data_Access
, которая выполняет подключение к базе данных.
Примечание: В верхней части этой функции вы можете видеть, что я определяю некоторые переменные для учетных данных базы данных.Обычно я не храню такие вещи в коде, я привожу эти учетные данные из файла INI за пределами общедоступной веб-папки. Но в этой демонстрации это помогает упростить задачу.
Функция dbConnect
пытается подключиться к базе данных и сохранить это соединение в переменной GLOBAL
, которая будет доступна для совместного использования с другими классами базы данных в течение жизни страницы PHP, создающей экземпляр класса. Если возникает ошибка, она возвращается к вызывающей функции в массиве.
Наконец, на изображении 2 ниже у нас есть функция getResultSetArray
в Data_Access
:
Функция getResultSetArray
принимает строку запроса в качестве параметра и использует установленную базу данных для выполнения запроса. Затем он помещает результаты в ассоциативный массив и возвращает его вызывающей функции. Если возникает ошибка, она также передается вызывающей функции.
Примечание: Причина, по которой я возвращаю все в виде массива ответов, заключается в обеспечении согласованности вызывающих функций. При этом мои вызывающие функции могут знать, что ответ всегда будет возвращаться в этой форме, пройден или не пройден, с кодом ответа, сообщением и любыми данными в ассоциативный массив с именем dataArray
. Этот ассоциативный массив легко использовать в PHP или Javascript.
После завершения Data_Access
у нас есть абстрактный класс, который может быть расширен нашими конкретными классами.Он предоставляет функции, реализующие код, который может использоваться всеми классами. Он не относится к какой-либо базе данных или таблице (особенно если вы удалите жестко заданные учетные данные в dbConnect
) и, следовательно, удовлетворяет требованиям абстрактного класса в PHP.
Теперь посмотрим на интерфейс.
Nautaskrá
Vafrakökur (например, печенье) eru smáar textaskrár sem vefsíður koma fyrir á tölvu inni, síma eða snjalltæki egar þú heimsækir þær.Almennt eru vafrakökur notaðar тиль bæta viðmót síðunnar ог тиль þess að vefsíðan muni mikilvægar upplýsingar frá fyrri heimsóknum þínum. Vafrakökur eru öruggar, þær innihalda ekki kóða og geta ekki verið notaðar til komast inn í tölvuna þína. Энгар тилраунир эру герар тиль и тенгья хеймсокн við persónugreinanlegar upplýsingar.
Af hverju notar nautaskra.net vafrakökur ?
Við notum vafrakökur til mælinga á heimsóknum á heimasíðu okkar. Umfer á vefinn eru mæld með Google Analytics.Að þýðir að skráður er tími og dagsetning heimsókna á vefinn, IP tölur þeirra sem heimsækja hann og frá hvaa vefsíðu heimsóknir koma, tegund vafra og st finri Vafrakökur eru notaðar í margvíslegum tilgangi eins og til dæmis að muna hvað notandi hefur valið í útfyllingu á eyðublaði á meðan hann er tengdur vefsvæðinu, r aggí vefsvæðinu, r kunna Lotukökur eyðast egar notandi fer af vefsvæði og eru því ekki vistaðar til lengri tíma.Viðvarandi vafrakökur vistast á tölvu notanda og muna val eða aðgerðir notanda á vefsvæði.
Hvernig er hægt að eyða vafrakökum ?
Allir vafrar bjóða upp á takmörkun á notkun á vafrakökum, eins er mögulegt að slökkva á eim í stillingum vafrans. Ólíkt er eftir vöfrum hvernig þetta er gert en leiðbeiningar má finna í hjálparvalmöguleika í vafranum sem ú notar. Einnig er hægt að eyða eim vafrakökum sem egar eru vistaðar hjá ér. Skrefin við að eyða vafrakökum eru ólík eftir vöfrum en leiðbeiningar um slíkt ma finna í hjálparvalmöguleika í vafranum sem ú notar.
Hægt er að nálgast allar upplýsingar um hvernig vafrakökur virka og hvernig hægt er að komast hjá notkun eirra á essari vefsíðu: http://www.allaboutcookies.org/
Разница между интерфейсом и абстрактным классом
Разница между интерфейсом и абстрактным классом Опубликовано 16 сентября 2017 г. Тони МарстонС поправками от 18 сентября 2017 г.
- Введение
- Абстрактный метод
- Статический метод
- Обычный метод
- Интерфейс
- Абстрактный класс
- Бетон (простой) класс
- Мифы об интерфейсах
- Сводка
- История изменений
- Комментарии
Это попытка объяснить различия между интерфейсом , абстрактным классом и не абстрактным классом в языке PHP.Реализация на других языках может немного отличаться.
Каждая из этих конструкций может содержать только определенные типы методов, поэтому необходимо сначала объяснить, что это такое.
Абстрактный метод определяется как сигнатура метода без тела метода, т. Е. Не имеет реализации.
При определении в абстрактном классе требуется префикс ключевого слова abstract . В этом нет необходимости, если они определены в интерфейсе, поскольку все методы в интерфейсе по умолчанию являются абстрактными.
Когда что-то, содержащее абстрактный метод, включается в неабстрактный класс, либо с помощью использования, либо с помощью ключевого слова extends, этот абстрактный метод должен быть определен в этом классе с той же сигнатурой, после чего тело метода также может быть определено.
Доступ к статическому методу можно получить без предварительного создания экземпляра его класса в объекте. Доступ к нему осуществляется с помощью выражения
Статический метод не может использовать псевдопеременную $ this
.
У простого метода есть подпись и тело, но тело может быть пустым. Это отличается от абстрактного метода, который может иметь подпись, но не иметь тела.
Если унаследован простой метод, его можно использовать в подклассе, не определяя его в подклассе.
Простой метод может использовать любой из модификаторов видимости public , private или protected .
Интерфейс определяет один или несколько абстрактных методов. Он не может содержать никаких простых или статических методов.
Интерфейс идентифицируется по ключевому слову interface перед именем интерфейса / класса
Интерфейс может содержать константы, но не переменные.
Не удается создать экземпляр интерфейса в объекте.
Никакие методы в интерфейсе не могут иметь модификаторы видимости, поскольку по умолчанию каждый метод является общедоступным.
Интерфейс может быть унаследован другим интерфейсом с помощью ключевого слова Implements.
Интерфейс может быть унаследован классом, абстрактным или не абстрактным, с помощью ключевого слова реализации.
Следующее описание абстрактного класса взято из Components, Frameworks, Patterns (PDF) Ральфа Э. Джонсона:
Абстрактный класс — это класс без экземпляров, поэтому он используется только как суперкласс. У абстрактного класса обычно есть по крайней мере одна нереализованная операция, отложенная до его подклассов. Поскольку абстрактный класс не имеет экземпляров, он используется как шаблон для создания подклассов, а не как шаблон для создания объектов.Фреймворки используют их как конструкции своих компонентов.
Интерфейс может содержать любую смесь абстрактных методов, простых и статических методов.
Абстрактный класс идентифицируется по ключевому слову abstract перед именем класса
Невозможно создать экземпляр абстрактного класса в объекте.
Он может наследовать один или несколько интерфейсов с помощью ключевого слова Implements.
Он может наследовать не более одного абстрактного класса с использованием ключевого слова extends.
Абстрактный класс не может наследовать от не абстрактного класса.
Любые абстрактные методы, которые наследуются либо от интерфейса, либо от другого абстрактного класса, не нужно определять как сигнатуры, и их реализации требуются только при наследовании неабстрактным классом.
Он может содержать любое количество констант, переменных и методов (абстрактных или иных).
Может содержать любое количество статических или простых методов.
Он не может содержать никаких абстрактных методов, иначе он должен быть абстрактным классом.
Может содержать любое количество констант и переменных.
Его можно создать в виде объекта.
Он может расширять не более одного класса, абстрактного или не абстрактного.
Может реализовывать любое количество интерфейсов.
Может быть унаследован другим классом, но не абстрактным классом.
Унаследованный класс известен как суперкласс или родительский класс , тогда как класс, который наследует, известен как подкласс или дочерний класс .
Если какие-либо абстрактные методы наследуются, то они должны быть определены с точно такой же сигнатурой и с любой желаемой реализацией.
Если какие-либо простые методы наследуются, их не нужно определять, но если они есть, они должны иметь одинаковую сигнатуру и с любой желаемой реализацией.
Если метод в суперклассе переопределен в подклассе , тогда реализация в подклассе будет выполняться во время выполнения, а не реализация в суперклассе .
Константы, переменные и методы, которые не наследуются, могут иметь любые модификаторы видимости.
Абстрактный метод, унаследованный от интерфейса, должен быть определен с такой же видимостью (общедоступный).
Абстрактный метод, унаследованный от абстрактного класса, может быть определен с такой же или менее ограничительной видимостью .
Моим первым языком с возможностью объектно-ориентированного программирования был PHP 4, который не поддерживал интерфейсы, только инкапсуляцию, наследование и полиморфизм, и я смог создать надежное и экономичное программное обеспечение, используя только эти три.Однако с тех пор, как я публиковал статьи о своем подходе, меня постоянно засыпали обвинениями в том, что я не «настоящий» объектно-ориентированный программист, потому что я не использую интерфейсы. Я предпочитаю игнорировать эти обвинения, потому что они основаны на множестве мифов и совершенно беспочвенны.
- Интерфейсы требуются на языках OO.
- Мусор. Интерфейсы были изобретены для решения проблемы, которая существовала несколько десятилетий назад, когда скорость обработки была всего лишь долей того, что есть сейчас, и требовался механизм, чтобы проверить, существует ли метод с такой сигнатурой в объекте до его вызова.Это нельзя было сделать во время выполнения, поэтому это было сделано во время компиляции. Пожалуйста, обратитесь к разделу «Полиморфизм и наследование независимо друг от друга». Эта проблема больше не существует в современных языках с современными высокоскоростными процессорами, поэтому, если проблема больше не существует, почему все еще необходимо ее решение?
- Интерфейсы предоставляют альтернативный тип наследования
- Я часто читал о двух разновидностях наследования:
- Наследование реализации — где сигнатуры методов и их реализации наследуются от суперкласса.
- Наследование интерфейса — когда от интерфейса «наследуется» только сигнатура метода.
Для меня это полное злоупотребление термином «наследование», поскольку на самом деле с интерфейсами ничего не наследуется. Если вы посмотрите определение наследования, вы увидите, что оно влечет за собой передачу чего-то существенного, без каких-либо усилий с их стороны. Если родственник умирает и оставляет вам состояние в своем завещании, вы внезапно обнаруживаете, что владеете этим состоянием без какой-либо веской причины, кроме того, что вас называют бенефициаром.
В объектно-ориентированном программировании наследование работает несколько иначе, поскольку вместо того, чтобы текущий владелец этой «сущности» (суперкласса) называет вас своим бенефициаром, любое количество подклассов может наследовать (используя ключевое слово extends ) от одного и того же суперкласс. Это означает, что все содержимое суперкласса затем используется любым количеством подклассов, при этом ни один из этих подклассов не известен суперклассу.
Не существует такой вещи, как наследование интерфейса , поскольку на самом деле ничего не передается получателю.Мало того, что нет реализации (вы должны ее кодировать самостоятельно), вы даже не «наследуете» сигнатуру метода, поскольку вы создали свой собственный дубликат. Это как сказать кому-то: «Поздравляю, вы только что унаследовали портфель, полный денег», а когда они спрашивают: «Хорошо, так где он?» вы говорите им, что они должны сами предоставить и деньги, и портфель. Итак, если на самом деле вам ничего не дается, потому что вы должны были предоставить это самостоятельно, что именно вы унаследовали? Нет ничего существенного, только концепция.
- Интерфейсы обеспечивают лучший стиль программирования
- В этой статье Википедии говорится следующее:
Использование интерфейсов позволяет использовать стиль программирования, называемый «программирование », для интерфейса . Идея этого подхода состоит в том, чтобы основывать логику программирования на интерфейсах используемых объектов, а не на деталях внутренней реализации. Программирование с использованием интерфейса снижает зависимость от специфики реализации и делает код более пригодным для повторного использования.
Это для меня полная чушь вздор.Во-первых, когда вы вызываете метод в объекте, вы не знаете, как этот метод реализован в этом объекте, только то, что существует метод с этой сигнатурой. Это позволяет вам вызывать один и тот же метод для другого объекта, который затем имеет другую реализацию. В этом суть полиморфизма, и у вас должен быть полиморфизм, прежде чем вы сможете использовать Dependency Injection (DI). Во-вторых, идея повторного использования кода включает в себя больше, чем дублированные сигнатуры методов, она включает в себя блок кода (реализация идеи), который определяется только один раз, а затем вызывается из нескольких мест вместо того, чтобы этот код дублировался в нескольких местах.В этом и заключается суть принципа DRY.
В статье «Наследование интерфейсов vs наследование реализации» автор утверждает следующее:
Концепция предпочтения наследования интерфейсов, вероятно, впервые пришла из дней программирования C ++ и COM, когда абстрактный класс использовался бы для определения методов в базовом классе, а наследующие классы требовались бы для реализации этих методов.
Это чушь, поскольку подкласс требуется только для реализации абстрактных методов, а абстрактный класс не должен содержать никаких абстрактных методов, только конкретные.Конкретные методы абстрактного класса автоматически наследуются подклассом, и их необходимо определять в подклассе только в случае изменения реализации.
- Наследование интерфейсов позволяет избежать сопряжения
- Затем в той же статье он задает вопрос: «Так почему же наследование интерфейсов предпочтительнее наследования реализации?» на что ответ:
Простой ответ — избежать связи между двумя компонентами приложения.
Идея о том, что вы можете избежать связывания, когда один модуль вызывает другой, говорит мне, что этот человек не понимает, что на самом деле означает связывание.Когда у вас есть приложение, состоящее из множества модулей, которые должны взаимодействовать между собой, у вас автоматически возникают связи и зависимости. Это неизбежно в модульном приложении. Возьмем следующие примеры:
Если ModuleA вызывает ModuleB, применяются следующие утверждения:
- Между ModuleA и ModuleB существует зависимость.
- ModuleA зависит от ModuleB, поскольку для выполнения своей задачи ему требуются услуги ModuleB.
- ModuleB не зависит от ModuleA, потому что он не вызывает ModuleA и, следовательно, не требует услуги ModuleA для выполнения своей задачи.
Зависимость между двумя модулями / объектами является двоичным условием — если один вызывает другой, то существует зависимость. Если ни один из них не вызывает другого, то зависимости нет.
- Между ModuleA и ModuleB существует связь.
- ModuleA связан с ModuleB, потому что он вызывает метод внутри ModuleB.
- ModuleB связан с ModuleA, потому что у него есть метод, который вызывается из ModuleA.
Аналогично, если один модуль вызывает другой, то есть связь.Если ни один из них не вызывает другого, то связи нет. Однако прочность муфты имеет разветвления, когда слабая связь считается хорошей, а плотная — плохой. Плотная связь проявляется, когда изменение в ModuleB вызывает волновой эффект соответствующих изменений в других модулях. Если вы измените подпись метода в модуле, вам автоматически придется изменить все те другие модули, которые ссылаются на эту подпись.
Невозможно полностью исключить связывание, поскольку полностью изолированное приложение не будет работать.Два тесно связанных модуля имеют меньше шансов на повторное использование, поэтому единственный способ гарантировать большее повторное использование кода — это иметь как можно более слабую связь. Например, если у меня есть контроллер C1 , который тесно связан с моделью M1 , то я не могу использовать этот контроллер с любой другой моделью, и я не могу использовать эту модель с любым другим контроллером. В моей структуре RADICORE я перешел на другой конец спектра, позволив использовать любой из более чем 50 контроллеров многократного использования с любым из моих классов моделей (которых в настоящее время более 400).Таким образом, минимизируя (что НЕ то же самое, что исключение) уровень связи, я максимизировал уровень повторного использования кода.
Идея о том, что внедрение зависимостей (DI) разъединяет взаимосвязанные модули, является полной ошибкой. Вы не можете использовать DI, если у вас нет полиморфизма, и у вас не может быть полиморфизма, если несколько объектов не используют одну и ту же сигнатуру (ы) метода, что обычно достигается этими объектами, унаследованными от одного и того же абстрактного класса. Возьмем следующий пример:
ModuleA вызывает ModuleB (n), где «n» идентифицирует конкретный модуль, который разделяет эту подпись.Использование DI ModuleA не содержит кода для определения того, какую версию ModuleB необходимо создать, это делается вне ModuleA, а затем вводится в него. Затем ModuleA вызывает метод для той версии ModuleB, которая была в него введена.
Здесь вы должны увидеть, что все еще существует как зависимость, так и связь между ModuleA и всеми версиями ModuleB, поскольку одна из них вызывает метод с использованием сигнатуры, определенной в другой, все, что произошло, это где конкретная версия ModuleB идентифицирован и создан.
- Наследование разрывает инкапсуляцию
- Это расширение идеи выше относительно связи. Когда я впервые услышал это, я искренне подумал, что это шутка, поскольку наследование и инкапсуляция, наряду с полиморфизмом, должны быть главными критериями того, что делает язык программирования объектно-ориентированным в первую очередь, так сказать, что два из этих трех нарушают друг в друге мне кажется, что они — полная чушь вздор. Тем не менее, есть некоторые комики, которые проповедуют эту идею как евангельскую истину.Если вы мне не верите, взгляните на следующее:
Если вы прочитаете эти статьи, то увидите, что в одной из них написано следующее:
Если производному классу разрешен доступ к членам, унаследованным от базового класса, изменения в базовом классе могут также потребовать обслуживания производного класса.
Обратите внимание на использование слов , если и может . Это показывает, что проблемы возможны только при определенных обстоятельствах и не гарантируются ни при каких обстоятельствах.Ответ на это должен быть очевиден — будьте осторожны, когда вносите изменения, и у вас не будет никаких проблем.
Другие говорят примерно следующее:
Он нарушает инкапсуляцию, поскольку предоставляет подклассу сведения о реализации его суперкласса.
Инкапсуляция связана с сокрытием информации, и когда вы наследуете от суперкласса, информация внутри этого суперкласса больше не скрывается в подклассе.Эти люди не понимают, что когда вы наследуете содержимое класса C1 в класс C2 , то полученный объект объединяет содержимое C1 с содержимым C2 .Все, что в C1 , что должно быть скрыто от C2 , должно иметь правильную видимость. Следовательно, любая проблема связана с реализацией концепции программистом, а не с самой концепцией.
Есть еще один момент, который упускают из виду большинство людей — «проблема» может материализоваться только тогда, когда вы наследуете от одного конкретного класса, чтобы создать совершенно другой конкретный класс. Таким образом, «решение» очевидно — создавать конкретный класс только путем наследования от абстрактного класса, как это было задокументировано еще в 1994 году в книге «Шаблоны проектирования: элементы многоразового объектно-ориентированного программного обеспечения».
Для меня это вопрос баланса. Вы должны взвесить преимущества наследования и недостатки. Преимущества наличия большого количества кода, который повторно используется в нескольких местах, что позволяет избежать необходимости дублирования кода, гарантированы в любое время. Недостатками большого количества общего кода является то, что , если вы вносите какие-либо изменения в базовый класс, может внести соответствующие изменения во все производные классы, но это возможно только при изменении базового класса.Другими словами, преимущества гарантированы, а недостатки — только возможности. Я боюсь, что, ИМХО, преимущества перевешивают недостатки огромным запасом , поэтому я буду продолжать использовать наследование, поскольку оно было разработано для использования.
Ненавижу интерфейсы, и не пользуюсь ими. Обратитесь к Минималистскому подходу к объектно-ориентированному программированию с помощью PHP для подробного объяснения.
Мне нравятся абстрактные классы, поскольку они позволяют использовать шаблон метода шаблона.
Есть люди, которые считают, что абстрактный класс может содержать только абстрактные методы, но они не понимают, что это не отличает его от интерфейса. Абстрактный класс предоставляет многоразовые реализации, а интерфейс — нет.
В моей структуре RADICORE, которая имеет дело с приложениями баз данных, каждый компонент модели на уровне Business представляет одну таблицу базы данных, и весь код, общий для таблиц базы данных, был определен один раз в одном классе абстрактной таблицы, который затем наследуется каждый из моих 400+ классов конкретных таблиц.Этот абстрактный класс заполнен более чем 200 конкретными методами, а не абстрактными методами, поэтому ни один из них не нужно определять и реализовывать в подклассе. Это обеспечивает огромных кода для многократного использования / совместного использования, и поскольку это должно быть целью ООП, я категорически отказываюсь признавать любую критику, которая говорит, что моя реализация ООП неверна.
Я никогда не наследую от одного конкретного класса, чтобы создать другой конкретный класс. Я расширяю конкретный класс только тогда, когда для другой пользовательской транзакции требуется другая реализация в одном или нескольких пользовательских методах перехвата.
Пожалуйста, включите JavaScript, чтобы просматривать комментарии от Disqus.
Последняя информация о примере абстрактного класса php
Для программистов PHP наиболее трудным моментом для понимания является применение этого знания в абстрактном классе PHP. Новичку еще не нужно использовать объектно-ориентированные знания для программирования, но более поздней разработки, используя классы для инкапсуляции или
Интерфейс отличается от абстрактного класса, интерфейс абстрактного класса отличается В чем разница между интерфейсом и абстрактным классом Что является основой вашего выбора в использовании интерфейсов и абстрактных классов? Понятия интерфейсов и
В этой статье в основном представлены примеры интерфейса php и абстрактных классов, а также даны подробные объяснения.если они вам нужны, вы можете обратиться к разделу 1. абстрактный класс 1. абстрактный класс относится к классу с абстрактными ключевыми словами, добавленными перед классом и
В этой статье в основном представлены примеры интерфейса php и абстрактных классов, а также даны подробные объяснения. если они вам нужны, вы можете обратиться к разделу 1. абстрактный класс 1. абстрактный класс относится к классу с абстрактными ключевыми словами, добавленными перед классом и
Разница между интерфейсом и абстрактным классом.В чем разница между интерфейсом и абстрактным классом? какова основа для использования интерфейса и абстрактного класса? Понятия интерфейсов и абстрактных классов —
.Эта статья знакомит с объектно-ориентированными абстрактными методами в PHP и использованием объектов клонирования абстрактного класса __call, а также знакомит с друзьями, которым нужно уметь учиться.Абстрактные методы и абстрактные классы В языке ООП класс может иметь один или
В чем разница между интерфейсом и абстрактным классом Какова основа вашего выбора для использования интерфейсов и абстрактных классов? Понятия интерфейсов и абстрактных классов различны. Интерфейс — это абстракция действия, а
В этой статье в основном представлены примеры использования интерфейса PHP и абстрактного класса, а также дано подробное объяснение, необходимость в друзьях может относиться к следующему абстрактному классу 1.Абстрактный класс — это класс, который имеет ключевое слово abstract в
.Абстрактный класс PHP, абстрактный PHP. Абстрактный класс PHP: для программистов на php наиболее трудным моментом является подсчет количества знаний о приложении абстрактного класса PHP. Как новичок, я еще не использовал объектно-ориентированный абстрактный класс PHP, php
Для программистов PHP наиболее трудным моментом для понимания является применение этого знания в абстрактном классе PHP.Новичку еще не нужно использовать объектно-ориентированные знания для программирования, но более поздней разработки, используя классы для инкапсуляции или
Абстрактный класс против интерфейса в PHP
Это бесконечное обсуждение для группы разработчиков. Да, это правда, потому что на первый взгляд абстрактный класс и интерфейс делают одно и то же. Прежде чем читать дальше, если вы хотите подробно изучить обе концепции, вы можете перейти по ссылкам ниже:
- Абстрактный класс в PHP
- Интерфейс в PHP
Итак, я надеюсь, что вы прочитали вышеупомянутые статьи и / или вы, возможно, уже имеете подробное представление о том, что означают эти две концепции, и, возможно, у вас также есть идея, почему написала эту статью.
Я уверен, что у вас должен возникнуть вопрос: Когда использовать какой?
Когда использовать какой?
Когда вы попытаетесь ответить на этот вопрос программным способом, вы окажетесь на том же месте, что и начали. Так что вместо того, чтобы заниматься программированием, я попытаюсь объяснить это по-другому.
Допустим, у вас есть два модуля с именами A и B. Проще говоря, если вы можете сделать слово A как B, тогда вам следует использовать абстрактный класс, но если вы можете сделать так, чтобы слово A могло выполнять как B, тогда вам следует использовать интерфейс.
Итак, на основе приведенного выше примера Интерфейс — это просто общий договор о поведении / функциональности между двумя или более модулями.
Допустим, у вас есть два модуля с именами A и B. Проще говоря, если вы можете сделать слово A как B, тогда вам следует использовать абстрактный класс, но если вы можете сделать так, чтобы слово A способно выполнять как B, тогда вам следует использовать интерфейс.
Позвольте мне попытаться объяснить эту концепцию на примере. Сначала просмотрите предложения ниже и четко их поймите:
- В организации есть сотрудники
- Сотрудник имеет зарплату, связанную со всеми из них
- Некоторые сотрудники, например разработчик, могут исправить ошибку
- Некоторые сотрудники, такие как QA, могут сообщать об ошибке
- Некоторые сотрудники, такие как Мнгт, могут брать длительный отпуск
- Некоторые сотрудники, такие как руководитель проекта, могут исправить ошибку и взять длительный отпуск
Надеюсь, вы прочитали шесть предложений выше и тоже поняли их.Теперь свяжите эти предложения с правилом, которое я написал для принятия решения между абстрактным классом и интерфейсом . Основываясь на приведенных выше предложениях, мы можем определить следующие классы и интерфейсы в нашем коде.
1 | // Классы, которые необходимо определить класс Сотрудник класс Разработчик класс QA класс Mngt класс ProjectManager // Интерфейсы, которые должны быть определены (это своего рода возможности и не привязаны только к сотрудникам) |
Теперь с указанным выше определением класса и интерфейса мы можем определить, что Employee является нашим базовым классом и который будет расширен всеми типами сотрудников, здесь Developer, QA, Mngt и Project Manager.Также класс Employee может определять / реализовывать любой метод, который может применяться ко всем типам сотрудников. В этом примере класс Employee будет содержать один абстрактный метод — generateSalary ().
1 | // Базовый класс |
Теперь, согласно нашему второму предложению, все четыре класса сотрудников должны расширять наш базовый класс, которым является Employee.Также все четыре типа сотрудников должны реализовывать соответствующие интерфейсы в зависимости от их возможностей.
Давайте посмотрим на блоки кода ниже, основанные на наших сценариях:
Некоторые сотрудники, например разработчик, могут исправить ошибку
1 | class Developer extends Сотрудник реализует fixBug {} |
Некоторые сотрудники, такие как QA, могут сообщать об ошибках
1 | класс QA расширяется Отчет о навесном оборудовании сотрудника Ошибка {} |
Некоторые сотрудники, такие как Mngt, могут брать длительный отпуск
1 | class Mngt extends Сотрудник орудия long Vacation {} |
Некоторые сотрудники, такие как руководитель проекта, могут исправить ошибку и взять длительный отпуск
1 | class ProjectManager extends Сотрудник реализует fixBug, longVacation {} |
Итак, основываясь на приведенных выше предложениях, мы можем использовать интерфейс и абстрактные классы определенным выше способом.Честно говоря, это лучший пример, который я когда-либо встречал по данной теме. Если вы все еще не понимаете эту тему, я бы посоветовал оставить эту тему и перейти к тому, что вам удобно, потому что вы можете добиться чего-то, используя любую из этих функций. Я знаю, что это может открыть здесь очень хорошее и здоровое обсуждение, так что будьте первым и начните конверсию по этой теме.
Примеры исходного кода для наших учебных модулей
Компоненты веб-решения Пример из учебного курса Well House ConsultantsПодробнее о компонентах веб-решения [ссылка]
Исходный код: примеры.txt Модуль: A100
Эта страница является только примером — вы запустили сценарий «Пример исходного кода
» на веб-сайте Well House Consultants, но
вы не сказали нам, какой пример вам нужен. Пожалуйста, перейдите по ссылкам
, чтобы найти конкретный пример
, который вы ищете.
Узнать об этом предмете
Книги по этой теме
Да. В нашей библиотеке более 700 книг. Книги Прикрывающее развертывание лампы перечислены здесь, и когда вы выбрали соответствующую книгу мы свяжем вас с Amazon для заказа.Другие примеры
Этот пример взят из нашего учебного модуля «Компоненты веб-решения». Вы найдете описание темы и некоторые другие тесно связанные примеры на индексной странице модуля «Компоненты веб-решения».Полное описание исходного кода
Вы можете узнать больше об этом примере на учебных курсах, перечисленных на этой странице, на котором вы получите полный набор обучающих заметок.Многие другие учебные модули доступны для загрузки (для ограниченного использования) с наш центр загрузки под Лицензия Open Training Notes.
Другие ресурсы
• В нашем центре решений есть ряд более длинных технических статей.• В нашем архиве форумов Opentalk есть центр вопросов и ответов.
• Лошадиный рот дает ежедневные подсказки или мысли.
• Дополнительные ресурсы доступны через ресурсный центр.
• Все эти ресурсы можно искать с помощью нашей поисковой системы
• И здесь есть глобальный индекс.
Назначение этого сайта
Это образец программы, демонстрация класса или ответ от учебный курс.Это основная цель заключается в предоставлении послекурсовых услуг клиентам, которые посещали наши общественное частное или на сайте курсы, но примеры сделаны обычно доступны при условиях, описанных ниже.Автор веб-сайта
Этот веб-сайт написан и поддерживается Консультанты Well House.Условия использования
Прошедшие участники наших учебных курсов могут использовать индивидуальные примеры в процессе их программирования, но необходимо проверить примеры, которые они используют, чтобы убедиться, что они подходят для их работа. Помните, что некоторые из наших примеров показывают вам, как , а не делать вещи — проверяйте в своих заметках. Well House Consultants не несет ответственности на предмет соответствия этих примеров программ потребностям клиентов.Авторские права на эту программу принадлежат Well House Consultants Ltd. запрещено использовать его для проведения собственных учебных курсов без нашего предварительного письменного разрешения.