В объектно-ориентированном программировании (англ. Object-Oriented Programming, сокращение: ООП) объект — это совокупность информации и описания способа обработки информации, а также абстракция реального мира.
В реальном мире мы сталкиваемся с такими объектами, как компьютеры, телевизоры, велосипеды и т. д.
Выделяют три основные характеристики объектов:
Поведение объекта: какие операции можно применять к объекту, включение и выключение света — это поведение.
Форма объекта: как объект реагирует на применение этих методов, цвет, размер, внешний вид.
Представление объектов: Представление объектов эквивалентно удостоверению личности, в котором конкретно различаются различия в одном и том же поведении и статусе.
Например, Animal — это абстрактный класс. Мы можем указать собаку и овцу, а собаки и овцы — это конкретные объекты. Они имеют атрибуты цвета, могут быть записаны, могут бегать и другие поведенческие состояния.
Класс — определяет абстрактные характеристики вещи. Определение класса включает форму данных и операции с данными.
Объект — это экземпляр класса.
Переменные-члены — переменные, определенные внутри класса. Значение этой переменной невидимо для внешнего мира, но к нему можно получить доступ через функции-члены. После создания экземпляра класса как объекта переменную можно назвать атрибутом объекта.
Функции-члены — определяются внутри класса и могут использоваться для доступа к данным объекта.
Наследование . Наследование — это механизм, с помощью которого подклассы автоматически совместно используют структуры данных и методы своего родительского класса. Это связь между классами. При определении и реализации класса вы можете сделать это на основе существующего класса, взять контент, определенный существующим классом, как свой собственный контент и добавить новый контент.
Родительский класс . Класс, унаследованный другими классами, может называться родительским классом, базовым классом или суперклассом.
Подкласс . Класс, который наследуется от других классов, называется подклассом или его также можно назвать производным классом.
Полиморфизм . Полиморфизм означает, что одна и та же функция или метод может применяться к нескольким типам объектов и получать разные результаты. Разные объекты могут давать разные результаты при получении одного и того же сообщения. Это явление называется полиморфизмом.
Перегрузка . Проще говоря, это ситуация, когда функции или методы имеют одно и то же имя, но разные списки параметров. Такие функции или методы с одинаковым именем и разными параметрами называются перегруженными функциями или методами.
Абстракция . Абстракция относится к абстрагированию объектов с согласованными структурами данных (атрибутами) и поведением (операциями) в классы. Класс — это абстракция, которая отражает важные свойства, связанные с приложением, игнорируя при этом другой нерелевантный контент. Деление на любой класс субъективно, но должно быть связано с конкретным применением.
Инкапсуляция . Инкапсуляция относится к связыванию свойств и поведения объекта, существующего в реальном мире, и помещению его в логическую единицу.
Конструктор — в основном используется для инициализации объекта при создании объекта, то есть присвоения начальных значений переменным-членам объекта. Он всегда используется вместе с оператором new в инструкции для создания объекта.
Деструктор — Деструктор (деструктор) В отличие от конструктора, когда объект завершает свой жизненный цикл (например, была вызвана функция, в которой находится объект), система автоматически запускает деструктор. Деструкторы часто используются для выполнения «очистки» (например, при создании объекта используйте new, чтобы открыть пространство памяти, которое должно быть освобождено с помощью delete в деструкторе перед выходом).
На рисунке ниже мы создали три объекта с помощью класса Car: Mercedes, BMW и Audi.
$mercedes = новый автомобиль ();$bmw = новый автомобиль ();$audi = новый автомобиль ();
Обычный формат синтаксиса для классов определения PHP следующий:
<?phpclass phpClass { var $var1; var $var2 = "константная строка"; function myfunc ($arg1, $arg2) { [..] } [..]}?>
Анализ заключается в следующем:
Классы определяются с помощью ключевого слова class, за которым следует имя класса.
Переменные и методы можно определить в паре фигурных скобок ({}) после имени класса.
Переменные класса объявляются с помощью var , переменные также можно инициализировать.
Определения функций аналогичны определениям функций PHP, но доступ к функциям возможен только через класс и объекты, которые он создает.
<?phpclass Site { /* Переменные-члены*/ var $url; var $title*/ function setUrl($par){ $this->url = $par } function getUrl(){ echo $this; ->url . PHP_EOL; } функция setTitle ($ par) {$this->title = $par } функция getTitle() { echo $this->title; }}?>
Переменная $this представляет собственный объект.
PHP_EOL — символ новой строки.
После создания класса мы можем использовать оператор new для создания экземпляров объектов этого класса:
$codercto = новый сайт;$taobao = новый сайт;$google = новый сайт;
В приведенном выше коде мы создали три объекта. Каждый из трех объектов независим. Теперь давайте посмотрим, как получить доступ к методам-членам и переменным-членам.
После создания экземпляра объекта мы можем использовать его для вызова методов-членов. Методы-члены объекта могут работать только с переменными-членами объекта:
// Вызов функции-члена для установки заголовка и URL-адреса $codercto->setTitle( "Учебное пособие по программированию");$taobao->setTitle( "Taobao" );$google->setTitle( "Поиск Google");$codercto- > setUrl( 'www.codercto.com' );$taobao->setUrl( 'www.taobao.com' );$google->setUrl( 'www.google.com' );// Вызовите функцию-член, чтобы получить заголовок и URL-адрес $codercto->getTitle();$taobao->getTitle();$google->getTitle();$codercto->getUrl();$taobao-> getUrl();$google->getUrl();
Полный код выглядит следующим образом:
<?php class Site { /* Переменные-члены */ var $ url ; /* Функции-члены */ function setUrl ( $par ) { $this -> url = $par } function getUrl (){ echo $ ; this -> URL PHP_EOL ; } функция setTitle ( $par ) { $this -> title = $ par } функция getTitle ( ) { echo $this - > title ; }} $codercto = new Site ; $taobao = new Site ; $google = new Site ; // Вызов функции-члена, установка заголовка и URL-адреса $codercto -> setTitle ( « $taobao -> setTitle ( » Taobao ) " ); $google -> setTitle ( "Поиск Google" ); $codercto -> setUrl ( 'www.codercto.com' ); $taobao -> setUrl ( 'www.taobao.com' ); $google -> setUrl ( 'www.google.com' ); // Вызов функции-члена для получения заголовка и URL-адреса $codercto -> getTitle (); $taobao -> getTitle ( ); $google -> getTitle (); $codercto -> getUrl (); $taobao -> getUrl () ; $google -> getUrl () ;
Выполняя приведенный выше код, результат вывода:
Учебное пособие для фермеров кода Taobao Поиск в Google www.codercto.comwww.taobao.comwww.google.com
Конструктор — это особый вид метода. В основном он используется для инициализации объекта при его создании, то есть присвоения начальных значений переменным-членам объекта и использования его с оператором new
в инструкции для создания объекта.
PHP 5 позволяет разработчикам определять метод как конструктор в классе со следующим синтаксисом:
void __construct ([ смешанные $args [, $... ]] )
В приведенном выше примере мы можем инициализировать переменные $url и $title с помощью метода конструктора:
функция __construct($par1, $par2) { $this->url = $par1; $this->title = $par2;}
Теперь нам больше не нужно вызывать методы setTitle и setUrl:
$codercto = новый сайт('www.codercto.com', 'Учебное пособие по программированию');$taobao = новый сайт('www.taobao.com', 'Taobao');$google = новый сайт('www.google . com', 'Поиск Google');// Вызовите функцию-член, чтобы получить заголовок и URL-адрес $codercto->getTitle();$taobao->getTitle();$google->getTitle();$codercto->getUrl();$taobao->getUrl(); $google ->getUrl();
Деструктор (деструктор) В отличие от конструктора, когда объект завершает свой жизненный цикл (например, была вызвана функция, в которой находится объект), система автоматически выполняет деструктор.
В PHP 5 появилась концепция деструкторов, аналогичная другим объектно-ориентированным языкам. Ее синтаксис следующий:
пустота __destruct (недействительно)
<?phpclass MyDestructableClass { function __construct() { print "constructorn"; $this->name = "MyDestructableClass" } function __destruct() { print "destroy" . $this->name "n" } }$obj = новый MyDestructableClass();?>
Выполняя приведенный выше код, результат вывода:
Конструктор уничтожает MyDestructableClass
PHP использует ключевое слово «extensions» для наследования класса. PHP не поддерживает множественное наследование. Формат следующий:
class Child расширяет Parent { // Часть кода}
В примере класс Child_Site наследует класс Site и расширяет его функции:
<?php // Дочерний класс расширяет категорию сайта class Child_Site расширяет сайт { var $category ($par) { $this->category = $par } function getCate(){ echo $this->category; }}
Если метод, унаследованный от родительского класса, не может удовлетворить потребности подкласса, его можно переписать. Этот процесс называется переопределением метода, также известным как переписывание метода.
В этом примере методы getUrl и getTitle переопределяются:
функция getUrl() { echo $this->url . PHP_EOL; return $this->url;} функция getTitle() { echo $this->title;
Контроль доступа PHP к свойствам или методам достигается путем добавления ключевых слов public (публичный), protected (защищенный) или Private (частный) впереди.
public: доступ к членам открытого класса можно получить откуда угодно.
protected: Доступ к защищенным членам класса возможен как для него самого, так и для его подклассов и родительских классов.
Частный: доступ к закрытым членам класса возможен только в том классе, в котором они определены.
Атрибуты класса должны быть определены как общедоступные, защищенные или частные. Если определено с помощью var, оно считается общедоступным.
<?php/** * Define MyClass */class MyClass { public $public = 'Public'; protected $protected = 'Protected'; Private $private = 'Private' function printHello() { echo $this->public; echo $this->protected; echo $this->private }}$obj = new MyClass();echo $obj->public; // Эта строка может быть выполнена обычным образом echo $obj->protected; // Эта строка выдаст фатальную ошибку echo $obj->private; // Эта строка также выдаст фатальную ошибку $obj->printHello(); // Вывод Public, Protected и Private/** * Define MyClass2 */ class MyClass2 расширяет MyClass{ // Публичные и защищенные могут быть переопределены, но частные, но не защищенные $protected = 'Protected2' function printHello() { echo $this->public echo; $this->protected; echo $this->private }}$obj2 = new MyClass2();echo $obj2->public; // Эта строка может быть выполнена обычным образом echo $obj2->private; // Privateecho нет; определено $obj2->protected; // Эта строка вызовет фатальную ошибку $obj2->printHello() // Вывод Public, Protected2 и Undefined?>;
Методы в классе могут быть определены как общедоступные, частные или защищенные. Если эти ключевые слова не заданы, метод по умолчанию является общедоступным.
<?php/** * Define MyClass */class MyClass{ // Объявляем общедоступный конструктор public function __construct() { } // Объявляем общедоступный метод public function MyPublic() { } // Объявляем защищенный метод protected function MyProtected( ) { } // Объявляем частный метод. Private function MyPrivate() { } // Этот метод является общедоступной функцией Foo() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); }}$myclass = new MyClass;$myclass->MyPublic(); // Эта строка может быть выполнена обычным образом $myclass->MyProtected(); Эта строка создаст фатальную ошибку $myclass->MyPrivate(); // Эта строка создаст фатальную ошибку $myclass->Foo() // Все могут быть выполнены как Public, protected, так и Private/** *; Define MyClass2 */class MyClass2 расширяет MyClass{ // Этот метод является общедоступной функцией Foo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); // Эта строка будет генерировать фатальную ошибку}}$myclass2 = new MyClass2;$myclass2->MyPublic() // Эта строка может быть выполнена обычным образом $myclass2->Foo2(); Как общедоступные, так и защищенные могут быть выполнены, но частные — нет. class Bar { public function test() { $this->testPrivate(); $this->testPublic(); public function testPublic() { echo "Bar: :testPublicn"; } частная функция testPrivate() { echo "Bar::testPrivaten"; }}class Foo расширяет Bar { public function testPublic() { echo "Foo::testPublicn"; } частная функция testPrivate() { echo "Foo::testPrivaten" }}$myFoo = new foo();$myFoo->test(); // Foo::testPublic?>
Используя интерфейс, вы можете указать, какие методы должен реализовать класс, но вам не нужно определять конкретное содержимое этих методов.
Интерфейс определяется с помощью ключевого слова интерфейса , как и определение стандартного класса, но все методы, определенные в нем, пусты.
Все методы, определенные в интерфейсе, должны быть общедоступными. Это особенность интерфейсов.
Чтобы реализовать интерфейс, используйте оператор реализации . Класс должен реализовывать все методы, определенные в интерфейсе, иначе будет сообщено о фатальной ошибке. Класс может реализовывать несколько интерфейсов. Разделяйте имена нескольких интерфейсов запятыми.
<?php// Объявляем интерфейс 'iTemplate'.interface iTemplate{ public function setVariable($name, $var); public function getHtml($template);}//Реализуем класс интерфейса, который Template реализует iTemplate{private $vars = array( ) ; публичная функция setVariable($name, $var) { $this->vars[$name] = $var } public function getHtml($template) { foreach($this->vars as $name => $value) {$template = str_replace('{'. $name. '}', $value, $template } return $template }};
Значения, которые остаются неизменными на протяжении всего класса, можно определить как константы. Нет необходимости использовать символ $ при определении и использовании констант.
Значение константы должно быть фиксированным значением и не может быть переменной, атрибутом класса, результатом математической операции или вызовом функции.
Начиная с PHP 5.3.0, классы можно вызывать динамически с использованием переменной. Но значение этой переменной не может быть ключевым словом (например, self, родительским или статическим).
<?phpclass MyClass {const Constant = 'постоянное значение'; функция showConstant() { echo self::constant }}echo MyClass::constant . PHP_EOL;$classname = "MyClass";echo $classname::constant . PHP_EOL // Начиная с версии 5.3.0 $class = новый MyClass();$class->showConstant();echo $class::constant PHP_EOL // Начиная с PHP 5.3.0?>
Любой класс должен быть объявлен абстрактным, если хотя бы один метод в нем объявлен абстрактным.
Классы, определенные как абстрактные, не могут быть созданы.
Метод, определенный как абстрактный, только объявляет вызывающий метод (параметры) и не может определять реализацию конкретной функции.
При наследовании абстрактного класса подкласс должен определить все абстрактные методы родительского класса, кроме того, контроль доступа к этим методам должен быть таким же (или более мягким), как и в родительском классе; Например, если абстрактный метод объявлен как защищенный, то метод, реализованный в подклассе, должен быть объявлен как защищенный или общедоступный и не может быть определен как частный.
<?phpabstract class AbstractClass{ // Обязательно для подклассов для определения этих методов абстрактная защищенная функция getValue(); // Обычный метод (не абстрактный метод) public function printOut() { print $this); - > getValue() . PHP_EOL; }} класс ConcreteClass1 расширяет AbstractClass {защищенная функция getValue() { return "ConcreteClass1" } публичная функция; prefixValue($prefix) { return "{$prefix}ConcreteClass1" }}class ConcreteClass2 расширяет AbstractClass { public function getValue() { return "ConcreteClass2" } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2" }}$class1 = новый ConcreteClass1;$class1->printOut();echo $class1->prefixValue('FOO_') . PHP_EOL;$class2 = new ConcreteClass2;$class2->printOut();echo $class2->prefixValue('FOO_') .
Выполняя приведенный выше код, результат вывода:
БетонКласс1FOO_ConcreteClass1БетонКласс2FOO_ConcreteClass2
Кроме того, методы дочернего класса могут содержать необязательные параметры, которых нет в абстрактном методе родительского класса.
Например, если подкласс определяет необязательный параметр, который не включен в объявление абстрактного метода родительского класса, он все равно может работать нормально.
<?phpabstract class AbstractClass{ // Нашему абстрактному методу необходимо определить только необходимые параметры. Параметры public function prefixName($name, $separator = ".") { if ($name == "Pacman") { $prefix = "Mr" } elseif ($name == "Pacman") { $prefix = "Миссис"; } else { $prefix = ""; } return "{$prefix}{$separator} {$name}" }}$class = new ConcreteClass;echo $class->prefixName("Pacman "), "n";echo $class->prefixName("Pac Woman"), "n";?>
Результат:
Мистер ПакманМиссис.
Объявив атрибут или метод класса как статический, вы можете получить к нему прямой доступ, не создавая экземпляр класса.
Статические свойства не могут быть доступны через объект класса, экземпляр которого был создан (но статические методы могут).
Поскольку статические методы не требуют вызова объекта, псевдопеременная $this недоступна в статических методах.
Статические свойства не могут быть доступны объектам через оператор ->.
Начиная с PHP 5.3.0, классы можно вызывать динамически с использованием переменной. Но значение этой переменной не может быть ключевыми словами self, родительский или статический.
<?phpclass Foo { public static $my_static = 'foo'; public function staticValue() { return self::$my_static; }}print Foo::$my_static .$foo = new Foo();print $foo- >staticValue() .PHP_EOL;?>
Результат выполнения вышеуказанной программы:
фуфуу
В PHP 5 добавлено новое ключевое слово Final. Если метод родительского класса объявлен как окончательный, дочерний класс не сможет переопределить этот метод. Если класс объявлен финальным, он не может быть унаследован.
При выполнении следующего кода будет сообщено об ошибке:
<?phpclass BaseClass {public function test() { echo "BaseClass::test() call" } Final public function moreTesting() { echo "BaseClass::moreTesting() call" }}class ChildClass; BaseClass { public function moreTesting() { echo "ChildClass::moreTesting() call" }}//. Сообщение об ошибке Неустранимая ошибка: невозможно переопределить конечный метод BaseClass::moreTesting()?>
PHP не будет автоматически вызывать конструктор родительского класса в конструкторе дочернего класса. Чтобы выполнить конструктор родительского класса, вам необходимо вызвать родительский::__construct() в конструкторе дочернего класса.
<?phpclass BaseClass { function __construct() { print "Метод конструктора в классе BaseClass" }}class SubClass расширяет BaseClass { function __construct() { родитель::__construct(); // Конструктор подкласса не может автоматически вызвать родительский класс; Метод конструктора класса print "Метод конструктора в классе SubClass" }}class OtherSubClass расширяет BaseClass { // Наследуем метод конструктора BaseClass}// Вызов конструктора BaseClass $obj = new BaseClass(); // Вызов конструкторов BaseClass и SubClass $obj = new SubClass() // Вызов конструктора BaseClass $obj = new OtherSubClass();?>
Результат выполнения вышеуказанной программы:
Метод конструктора в классе BaseClass Метод конструктора в классе SubClass Метод конструктора в классе BaseClass