Инициализация класса (создание объекта) Объект класса - представитель класса, который имеет свое уникальное состояние и поведение. Для объявления объекта необходимо использовать оператор new: Объект = new Имя_класса; PHP: $myObj = new newClass(); Свойства класса Свойство – это переменные, хранимые в классе; перед именем свойства ставится один из следующих модификаторов (public, protected, private). Также есть ключевое слово var, но его время ушло (остался в 4-й версии PHP). Описание свойств PHP: class newClass { public $property1; protected $property2 = "value2"; private $property3; } Доступ к свойствам класса Доступ к свойствам класса за пределами класса реализуется так: объект->имя_свойства; (знак доллара у свойства не ставится!) PHP: $myObj = new newClass(); $myObj->property1; Изменение значения свойств PHP: $myObj->property2 = "Тут меняем значение"; Методы класса Метод – это функция, определенная внутри класса. У функции по умолчанию стоит модификатор public (то есть его можно не писать перед функцией). Описание методов PHP: class newClass { function myMethod($var1,$var2){ // по умолчанию это // общедоступный метод (public) // операторы } } Вызов метода PHP: $myObj = new newClass(); $myObj->myMethod('v1','v2'); $this Доступ к свойству класса внутри класса реализуется при помощи оператора($this): $this-> имя_свойства; (знак доллара у свойства не ставится!) Доступ к методу класса из другого метода класса также осуществляется с помощью ключевого слова $this. PHP: class newClass { public $property1; function myMethod(){ echo($this->property1); // Вывод значения свойства } function callMethod(){ $this->myMethod(); // Вызов метода } } Конструкторы и деструкторы Конструктор класса – это специальный метод, который автоматически вызывается в момент создания объекта. Круглый скобки за наименованием класса (при инициализации объекта) нужны для передачи параметров функции конструктору. Деструктор – специальный метод, который автоматически вызывается при удалении объекта. P.s. Порядок удаления объектов не определен, но стоит отметить, что объекты удалятся по завершении кода (порядок удаления объектов определить нельзя), и вызовется метод __destruct. Объект можно удалить принудительно: unset(имя_объекта). PHP: class newClass { public $property; function __construct($var){ $this->property = $var; echo "Вызываем конструктор"; } function __destruct(){ echo "Вызываем деструктор"; } } $obj = new newClass("Значение"); //Вызываем конструктор unset($obj); //Вызываем деструктора (принудительно) Псевдо-константы __METHOD__ и __CLASS__ Псевдо-константы __METHOD__ и __CLASS__ . Вместо __METHOD__ будет подставлено: имя_класса::имя_метода; __CLASS__ будет подставлено имя_класса. PHP: class newClass { function myMethod(){ echo __METHOD__; } function getClassName(){ echo __CLASS__; } } $obj = new newClass(); $obj->myMethod();// newClass::myMethod $obj->getClassName();// newClass Новые принципы работы с объектами Объекты передаются по ссылке, а не по значению PHP: class newClass { public $property; } $myObj = new newClass(); $myObj->property = 1; $myObj2 = $myObj; $myObj2->property = 2; print($myObj->property); // Выведет 2 print($myObj2->property); // Выведет 2 Клонирование объекта При клонировании (clone) конструктор не вызывается. Существует специальный метод __clone, который вызывается при клонировании объекта. Явное копирование объектов PHP: class newClass { public $property; } $myObj = new newClass(); $myObj->property = 1; $myObj2 = clone $myObj; // создаем копию объекта, в 4-й версии php было так: $myObj2 = &$myObj; // в 5-й версии PHP & с объектами не работает $myObj2->property = 2; print($myObj->property); // Печатает 1 print($myObj2->property); // Печатает 2 Наследование(полиморфизм) Один класс может наследовать другой класс. Для этого существует специальное ключевое слово - extends. PHP: class Machine { public $numWheels = 4; function printWheels() { echo $this->numWheels; } } class Toyota extends Machine { public $country = 'Japan'; function printCountry() { echo $this->country; } } $myMachine = new Toyota(); $myMachine->printWheels(); $myMachine->printCountry(); Перегрузка методов Перегрузка методов – в классе, который наследует другой класс, можно описать такой же метод, который есть в родительском классе, причем вновь описанный метод перезапишет метод родительского класса. Пример: PHP: class Machine { public $numWheels = 4; function printWheels() { echo $this->numWheels; } } class Toyota extends Machine { public $country = 'Japan'; function printCountry() { echo $this->country; } function printWheels() { echo "Перегруженный метод printWheels() "; } } $myMachine = new Toyota(); $myMachine->printWheels(); Parent parent::имя_метода, данная конструкция позволяет обратиться к родительскому методу. PHP: class Machine { public $numWheels = 4; function printWheels() { echo $this->numWheels; } } class Toyota extends Machine { public $country = 'Japan'; function printWheels() { echo "Перегруженный метод printWheels() "; parent:: printWheels(); } } $myMachine = new Toyota(); $myMachine->printWheels(); Модификаторы доступа: public, protected, private public (общедоступный) - позволяет иметь доступ к свойствам и методам классам из любого места protected (защищенный) - позволяет иметь доступ и родительскому (в котором определен сам член класса), и наследуемым классам private (закрытый) - ограничивает область видимости так, что доступ к нему имеет только тот класс, в котором объявлен сам элемент Модификаторы доступа: как это работает? PHP: $obj = new newClass(); echo $obj->public; //ДА echo $obj->protected; //НЕТ! echo $obj->private; //НЕТ $obj->myMethod(); PHP: class newClass { public $public = 1; protected $protected = 2; private $private = 3; function myMethod(){ echo $this->public; //ДА echo $this->protected; //ДА echo $this->private; //ДА } } PHP: $obj1 = new NewClass(); echo $obj1->public; //ДА echo $obj1->protected; //НЕТ! echo $obj1->private; //НЕТ $obj1->newMethod(); PHP: class NewClass extends newClass { function newMethod(){ echo $this->protected; //ДА echo $this->private; //НЕТ $this->myMethod(); } } Обработка исключений У нас есть кусок кода, в котором может произойти какая-нибудь ошибка; данный кусок кода помещается в блок под названием try; в том месте, где-может произойти ошибка, ставится ключевое слово throw; для отлова произошедшей ошибки описывается блок catch (ловушка), туда приходит ошибка, с которой мы можем работать. PHP: try { $a = 1; $b = 0; if($b == 0) throw new Exception("Деление на 0!"); echo $a/$b; } catch(Exception $e){ echo "Произошла ошибка - ", $e->getMessage(), // Выводит сообщение " в строке ", $e->getLine(), // Выводит номер строки " файла ", $e->getFile(); // Выводит имя файла } Создание собственных исключений PHP: сlass MathException extends Exception { function __construct($message) { parent::__construct($message); } } try { $a = 1; $b = 0; // MathException - имя класса для создания собственного исключения if ($b == 0) throw new MathException("Деление на 0!"); echo $a / $b; } catch (MathException $e) { echo "Произошла математическая ошибка ", $e->getMessage(), " в строке ", $e->getLine(), " файла ", $e->getFile(); } Перебор свойств объекта PHP: class Person { public $name; public $yearOfBorn; function __construct($name, $yearOfBorn){ $this->name = $name; $this->yearOfBorn = $yearOfBorn; } } $billGates = new Person(‘Bill Gates’,1955); foreach($billGates as $name=>$value){ print($name.’: ’.$value.’ ’); } Константы класса Константы – это константы класса, то есть они не принадлежат ни одному объекту. За пределами кода к константе можно обратиться следующим образом: имя_класса::имя_константы. Если мы хотим обратиться к константе в пределах класса, то нужно использовать ключевое слово self: self::имя_константы. PHP: class Person { const HANDS = 2; function printHands(){ print (self::HANDS);// NOT $this! Обращаемся к константе внутри класса } } print ('Количество рук: '.Person::HANDS); // Обращаемся к константе за пределами класса Абстрактные методы и классы Абстрактный класс в php - это так называемый базовый класс, не предназначенный для создания его экземпляров (объектов). Основной смысл и назначение абстрактных классов заключается в расширении возможностей его дочерних классов. Классы могут быть абстрактными. Абстрактный класс позволяет нам абстрагироваться от незначительных вещей, тем самым предоставляя нам возможность сконцентрироваться на более тонких нюансах. В абстрактном классе могут быть абстрактные методы (перед function стоит ключевое слово abstract). Абстрактный метод – это метод без реализации (отсутствуют фигурный скобки). Абстрактный метод обязательно должен быть описан (перезагружен) в классе-наследнике. Преимущество в использовании абстрактных методов: для каждого класса-наследника можно описать свое уникальное поведение абстрактного метода. PHP: abstract class Machine { // абстрактный класс public $petrol; function startEngine(){ print('Двигатель зав?лся!'); } abstract function stopEngine(); } class InjectorMachine extends Machine { public function stopEngine(){ print('Двигатель остановился!'); } } $myMegaMachine = new Machine();//Ошибка! $myMegaMachine = new InjectorMachine(); $myMegaMachine->startEngine(); $myMegaMachine->stopEngine(); Интерфейсы Существует еще один тип абстрактного класса – интерфейс. Интерфейс – это абстрактный класс, который содержит только абстрактные методы. Перед таким классом вместо слова abstract пишется interface. От интерфейса наследование происходит не через ключевое слово extends, а через ключевое слово implements. PHP: interface Hand { function useKeyboard(); function touchNose(); } interface Foot { function runFast(); function playFootball(); } class Person implements Hand { public function useKeyboard(){ echo 'Use keyboard!'; } public function touchNose(){ echo 'Touch nose!'; } public function runFast(){ echo 'Run fast!'; } public function playFootball(){ echo 'Play football!'; } } $vasyaPupkin = new Person(); $vasyaPupkin->touchNose(); Финальные методы и классы Перед методом ставится ключевое слово final, этим мы запрещаем перезагружать (перезаписывать) данный метод. Класс также можно объявить финальным. PHP: class Mathematics { final function countSum($a,$b){ print('Сумма: ' . $a + $b); } } class Algebra extends Mathematics { // Возникнет ошибка public function countSum($a,$b){ $c = $a + $b; print("Сумма $a и $b: $c"); } } PHP: final class Breakfast { // финальный класс function eatFood($food){ print("Скушали $food!"); } } // Возникнет ошибка class McBreakfast extends Breakfast { // Описание класса } Статические свойства и методы класса Статические методы и свойства класса (плюс константы класса) принадлежат классу, то есть они общие для всех объектов класса. К ним нельзя обратиться посредством ‛стрелки‛, а только через :: (внутри класса используется: self::$имя_свойства; за пределами класса: имя_класса::$имя_свойства). Статическое свойство, как и метод, объявляется через ключевое слово static. Как вы догадываетесь, внутри статического метода this использовать нельзя (такие методы не связаны с объектами). PHP: class CookieLover { static $loversCount = 0; // это статическое свойство, и компилятор не // будет его удалять после завершения работы функции __construct function __construct(){ ++self::$loversCount; } static function welcome(){ echo 'Добро пожаловать в клуб любителей булочек!'; //Никаких $this внутри статического метода! } } $vasyaPupkin = new CookieLover(); $frosyaBurlakova = new CookieLover(); print ('Текущее количество любителей булочек: '.CookieLover::$loversCount); print (CookieLover::welcome()); Ключевое слово instanceof Иногда требуется узнать: является ли текущий объект наследником того или иного класса, или интерфейса. Для этого используется ключевое слово instanceof. PHP: class Person {} $myBoss = new Person(); if($myBoss instanceOf Person) print('Мой Босс – человек!'); // вернет true, если класс Person есть в предках объекта $myBoss class Woman extends Person {} $englishQueen = new Woman(); if($englishQueen instanceOf Person) print('Английская королева – тоже человек!'); interface LotsOfMoney {} class ReachPeople implements LotsOfMoney {} $billGates = new ReachPeople(); if($billGates instanceOf LotsOfMoney) print('У Билла Гейтса много денег!'); Функция __autoload() Если PHP натыкается на несуществующий класс, при инициализации объекта, то он ищет функцию __autoload, передавая в функцию __autoload имя неназванного класса. И PHP вызовет эту функцию перед выводом ошибки об отсутствии класса. PHP: function __autoload($cl_name){ // $cl_name - имя не найденного класса print('Попытка создать объект класса '.$cl_name); } $obj = new undefinedClass(); Методы доступа к свойствам объекта Метод __set() будет выполнен при записи данных в недоступные свойства (которых нет в классе). Метод __get() будет выполнен при чтении данных из недоступных свойств (которых нет в классе). PHP: class newClass { private $properties; function __get($name){ print("Чтение значения свойства $name"); return $this->properties[$name]; } function __set($name,$value){ // в нашем случае $name это property, $value равно 1 print("Задание нового свойства $name = $value"); $this->properties[$name] = $value; } } $obj = new newClass; $obj->property = 1; // Запись нового свойства $a = $obj->property; // Чтение значения свойства print $a; // 1 Перегрузка вызова несуществующих методов Если мы обращаемся к методу которого нет, то PHP ищет метод __call (1-й параметр – это имя несуществующего метода, 2-й – массив аргументов). PHP: class newClass { function __call($name, $params){ print("Попытка вызова метода $name со следующими параметрами: "); print_r($params); } } $obj = new newClass(); $obj->megaMethod(1,2,3,"четыре"); Метод __toString() Метод __toString() позволяет классу решать самостоятельно, как он должен реагировать при преобразовании в строку. Например, что напечатает echo $obj;. Этот метод должен возвращать строку, иначе выдастся неисправимая ошибка E_RECOVERABLE_ERROR. PHP: class newClass { function __toString(){ return 'Вызван метод __toString()'; } } $obj = new newClass(); // Вызван метод __toString() echo $obj; (c) dnzl
Говорить что интерфейс это тип абстрактного класса считаю грубейшей ошибкой. Интерфейс определяет какие методы должен реализовывать класс который его имплементирует, и в то же время не содержит реализации этих методов. Любой класс может имплементировать несколько интерфейсов. PHP: // Серверу не важно какой именно клиент, ему важно чтобы у него были методы интерфейса, чтобы его опросить$server->ask(Askable $client); Абстрактный класс определяет базовую структуру всех дочерних классов, может содержать как абстрактные методы, так и реализованные. PHP: //Имя любой машины будет передаваться в конструкторе у любого из потомков, поэтому метод getName можно реализовать уже в базовом классе. А скорость, положим, будет определяться у каждого потомка по-своему.abstract class Car { abstract public function getSpeed(); publict function getName() { echo $this->name; }} Абстрактный класс является начальным структурным элементом иерархии классов, а интерфейс позволяет строить абстрактные договоренности в вашем API. Почитайте про проблемы множественного наследования и откуда всялись интерфейсы. Так же советую ознакомиться с принципом Inversion of Control