Объектно-ориентированное программирование (ООП) в PHP
Узнайте об ООП в PHP: классы, объекты, инкапсуляция, наследование и полиморфизм с практическими примерами кода.
Объектно-ориентированное программирование (ООП) — это парадигма программирования, построенная вокруг концепции «объектов», которые объединяют данные (свойства) и поведение (методы), работающие с этими данными. Вместо того чтобы разбрасывать связанные переменные и функции по всему скрипту, ООП позволяет группировать их в самодостаточные единицы, моделирующие сущности приложения — User, Order, Product.
В этой главе рассматриваются два основных понятия ООП в PHP — классы и объекты — а также три идеи, которые вы будете использовать с ними каждый день: инкапсуляция, наследование и полиморфизм. По завершении вы сможете уверенно читать и писать PHP-классы и понимать, какая возможность решает какую задачу.
Что такое классы и объекты в PHP ООП?
Класс — это шаблон. Он описывает какие данные хранит объект и что он умеет делать, но сам по себе не является вещью — так же как архитектурный план — это не дом. Объект — это конкретный экземпляр, созданный по этому шаблону с помощью ключевого слова new. Из одного класса можно создать много объектов, каждый со своими данными.
| Термин | Что это такое | Пример |
|---|---|---|
| Класс | Шаблон (определение) | class User { ... } |
| Объект | Живой экземпляр класса | $alice = new User(...) |
| Свойство | Переменная, принадлежащая объекту | $this->email |
| Метод | Функция, принадлежащая классу | getEmail() |
Хороший способ запомнить: класс — это форма для печенья, объекты — само печенье. Классы и объекты являются строительными блоками ООП в PHP.
Определение классов в PHP
Классы в PHP определяются с помощью ключевого слова class, за которым следует имя класса. Свойства и методы класса определяются внутри его определения, в фигурных скобках ({}). Ниже приведён пример определения класса в PHP:
Пример определения класса в PHP
class User {
public $username;
public $email;
public function __construct($username, $email) {
$this->username = $username;
$this->email = $email;
}
public function getUsername() {
return $this->username;
}
public function getEmail() {
return $this->email;
}
}В этом примере класс User имеет два свойства, $username и $email, и два метода, getUsername() и getEmail(). Метод __construct — это специальный метод-конструктор в PHP: он запускается автоматически в момент создания объекта, что делает его естественным местом для задания начального состояния объекта. Внутри любого метода $this ссылается на текущий объект, поэтому $this->username означает «свойство username этого объекта». Подробнее о конструкторах и соответствующем методе очистки читайте в PHP Constructor и PHP Destructor.
Создание объектов из классов
Чтобы создать объект из класса, используйте ключевое слово new, за которым следует имя класса. Вот пример создания объекта из класса User:
Создание объекта из класса в PHP с помощью ключевого слова new
$user = new User("John Doe", "[email protected]");Это создаёт новый объект User и сохраняет его в переменной $user. Доступ к свойствам и методам объекта осуществляется с помощью оператора стрелки (->). Вот пример обращения к свойствам и методам объекта $user:
Обращение к свойствам и методам объекта в PHP с помощью оператора стрелки
echo $user->username; // Outputs: "John Doe"
echo $user->email; // Outputs: "[email protected]"
echo $user->getUsername(); // Outputs: "John Doe"
echo $user->getEmail(); // Outputs: "[email protected]"Инкапсуляция: управление доступом к данным
В приведённых выше примерах каждое свойство объявлено как public, то есть любой код может читать или изменять его напрямую ($user->email = "..."). Это удобно, но рискованно — позволяет остальному коду программы перевести объект в недопустимое состояние. Инкапсуляция — это практика скрытия внутреннего устройства объекта и предоставления вместо него контролируемого интерфейса.
PHP предоставляет три модификатора видимости для свойств и методов:
| Модификатор | Доступен из | Когда использовать |
|---|---|---|
public | Отовсюду | Член является частью официального интерфейса объекта. |
protected | Класса и его подклассов | Подклассам он нужен, но внешний код не должен иметь доступа. |
private | Только того же класса | Член является внутренней деталью реализации. |
Объявив свойство как private и предоставив методы для его чтения и изменения, вы сосредотачиваете валидацию в одном месте:
<?php
class BankAccount
{
private $balance = 0;
public function deposit($amount)
{
if ($amount <= 0) {
throw new InvalidArgumentException("Deposit must be positive.");
}
$this->balance += $amount;
}
public function getBalance()
{
return $this->balance;
}
}
$account = new BankAccount();
$account->deposit(100);
$account->deposit(50);
echo $account->getBalance(); // Outputs: 150Поскольку $balance объявлен как private, внешний код не может напрямую установить отрицательное значение — каждое изменение должно проходить через deposit(), где и хранится правило. Подробнее о трёх ключевых словах читайте в PHP Access Modifiers.
Наследование в PHP ООП
Наследование — это возможность ООП, которая позволяет классам наследовать свойства и методы родительских классов. Это даёт разработчикам возможность создавать новые классы на основе существующих, не переписывая весь код заново. В PHP наследование определяется с помощью ключевого слова extends. Вот пример наследования в PHP:
Пример наследования в PHP — возможность ООП, позволяющая классам наследовать свойства
class Admin extends User {
public $permissions;
public function __construct($username, $email, $permissions) {
parent::__construct($username, $email);
$this->permissions = $permissions;
}
public function getPermissions() {
return $this->permissions;
}
}В этом примере класс Admin расширяет класс User и наследует его свойства и методы. У класса Admin также есть собственное свойство $permissions и метод getPermissions(). Ключевое слово parent:: используется для вызова метода __construct родительского класса, что позволяет классу Admin повторно использовать логику из класса User без её дублирования. Класс в PHP может расширять только одного родителя. Подробнее читайте в PHP Inheritance.
Полиморфизм в PHP ООП
Полиморфизм — это возможность ООП, которая позволяет обращаться с объектами разных классов как с объектами одного класса. Это позволяет разработчикам писать универсальный код, способный работать с объектами различных классов при условии, что у них есть одинаковые методы. В PHP полиморфизм достигается путём определения общих методов в родительских классах и их реализации в дочерних классах. Вот пример полиморфизма в PHP:
Пример полиморфизма в PHP
<?php
class User
{
public $username;
public $email;
public function __construct($username, $email)
{
$this->username = $username;
$this->email = $email;
}
public function getUsername()
{
return $this->username;
}
public function getEmail()
{
return $this->email;
}
public function showInfo()
{
echo "Username: " . $this->username . "\n";
echo "Email: " . $this->email . "\n";
}
}
class Admin extends User
{
public $permissions;
public function __construct($username, $email, $permissions)
{
parent::__construct($username, $email);
$this->permissions = $permissions;
}
public function getPermissions()
{
return $this->permissions;
}
public function showInfo()
{
parent::showInfo();
echo "Permissions: " . $this->permissions . "\n";
}
}
$user = new User("John Doe", "[email protected]");
$admin = new Admin("Jane Doe", "[email protected]", ["read", "write", "delete"]);
$users = [$user, $admin];
foreach ($users as $user) {
$user->showInfo();
}В этом примере класс User и класс Admin оба имеют метод showInfo(). При вызове метода showInfo() на объекте вызывается правильная реализация метода в зависимости от типа объекта. Это позволяет циклу foreach обращаться с объектами $user и $admin как с объектами одного типа, даже несмотря на то что они являются экземплярами разных классов.
Заключение
Объектно-ориентированное программирование (ООП) — мощная парадигма, широко используемая в PHP для создания масштабируемых и поддерживаемых веб-приложений. Классы и объекты являются строительными блоками; инкапсуляция, наследование и полиморфизм — это возможности, позволяющие писать эффективный, повторно используемый код. Освоив их, вы легко разберётесь в остальной объектной модели PHP.
Куда двигаться дальше:
- PHP Constructor — правильная инициализация объектов.
- PHP Access Modifiers —
public,protectedиprivateв деталях. - PHP Inheritance — расширение и переопределение классов.
- PHP Abstract Classes — определение частичных шаблонов, которые должны реализовывать подклассы.
- PHP Interfaces — обеспечение единого контракта для несвязанных классов.
- PHP Static Methods — методы, принадлежащие классу, а не экземпляру.