Классы и объекты PHP, основы
Инициализация класса (создание объекта)
Объект класса - представитель класса, который имеет свое уникальное состояние и поведение.
Для объявления объекта необходимо использовать оператор 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
|
PHP
|
PHP
|
PHP
|
Обработка исключений
У нас есть кусок кода, в котором может произойти какая-нибудь ошибка; данный кусок кода помещается в блок под названием 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;
Комментарии к статье
Зачетище!!!! Статья краткая, но безумно содержательная... В закладки!!!
Хотя подумал сейчас и понял что не хватает информации о трейтах....
Отличная статья, всё очень кратно и по полочкам.
Хорошо подана информация, мне понравилось, добавил в закладки.
Спасибо, кратко и понятно
Респект за статью!
круто!!! можно дополнять статью еще чем-нибудь новым.
отличная статья, Автору зачёт :)
Отличная, но не хватате результата работы кода, например для статических метлов.
спасибо, все что нужно в одном месте
Лучшая статья которую я видел в поиске. Спасибо автору!
Лучшая статья которую я видел в поиске. Спасибо автору!
крутая статья - четко грамотно и понятно
Неплохо, спасибо!
В интерфейсах неточность. Может ввести в заблуждение. Интерфейса два (hand,foot) а в имплементах только hand.
В интерфейсах неточность. Может ввести в заблуждение. Интерфейса два (hand,foot) а в имплементах только hand.
СПАСИБО! БОЛЬШОЕ ЧЕЛОВЕЧЕСКОЕ!