Advertisement
  1. Code
  2. Coding Fundamentals
  3. OOP

Объектно-ориентированный PHP с классами и объектами

Scroll to top
Read Time: 10 min

() translation by (you can also view the original English article)

В этой статье мы исследуем основы объектно-ориентированного программирования на PHP. Начнем с введения в классы и объекты, а  во второй половине статьи обсудим несколько продвинутых понятий, таких как наследование и полиморфизм.

Что такое объектно-ориентированное программирование (ООП)?

Объектно-ориентированное программирование, обычно называемое ООП - это подход, который вам помогает разрабатывать сложные приложения таким образом, чтобы они легко поддерживались и масштабировались в течение длительного времени. В мире ООП реальные понятия Person, Car или Animal рассматриваются как объекты. В объектно-ориентированном программировании вы взаимодействуете с вашим приложением, используя объекты.  Это отличается от процедурного программирования, когда вы, в первую очередь, взаимодействуете с функциями и глобальными переменными.

В ООП существует понятие «class», использываемое для моделирования или сопоставления реального понятия с шаблоном данных (свойств) и функциональных возможностей (методов)«Оbject» - это экземпляр класса, и вы можете создать несколько экземпляров одного и того же класса. Например, существует один класс Person, но многие объекты person могут быть экземплярами этого класса - dan, zainab, hector и т. д.

Например, для класса Person могут быть name, age и phoneNumber. Тогда у каждого объекта person для этих свойств будут свои значения.

Вы также можете определить в классе методы, которые позволяют вам манипулировать значениями свойств объекта и выполнять операции над объектами. В качестве примера вы можете определить метод save, сохраняющий информацию об объекте в базе данных.

 Что такое класс PHP?

Класс - это шаблон, который представляет реальное понятие и определяет свойства и методы данного понятия. В этом разделе мы обсудим базовую анатомию типичного класса PHP.

Лучший способ понять новые концепции - показать это на примере. Итак, давайте рассмотрим в коде класс Employee, который представляет объект служащего.

1
<?php
2
class Employee
3
{
4
  private $first_name;
5
  private $last_name;
6
  private $age;
7
 
8
  public function __construct($first_name, $last_name, $age)
9
  {
10
    $this->first_name = $first_name;
11
    $this->last_name = $last_name;
12
    $this->age = $age;
13
  }
14
15
  public function getFirstName()
16
  {
17
    return $this->first_name;
18
  }
19
20
  public function getLastName()
21
  {
22
    return $this->last_name;
23
  }
24
25
  public function getAge()
26
  {
27
    return $this->age;
28
  }
29
}
30
?>

Оператор class Employee в первой строке определяет класс Employee. Затем мы продолжаем объявлять свойства, конструктор и другие методы класса.

Свойства класса в PHP

Вы можете думать о свойствах класса как о переменных, которые используются для хранения информации об объекте.  В приведенном выше примере мы определили три свойства - first_name, last_name и age. В большинстве случаев доступ к свойствам класса осуществляется через созданные объекты.

Эти private свойства могут быть доступны только внутри класса. Данный подход - самый безопасный уровень доступа к свойствам. Позже в уроке мы обсудим различные уровни доступа к свойствам и методам класса.

Конструкторы для классов PHP

Конструктор - это специальный метод класса, который вызывается автоматически при инстанцинации объекта. В следующих разделах мы увидим, как инстанцировать объекты, но сейчас вам нужно просто знать, что конструктор используется для инициализации свойств объекта при создании объекта.

Вы можете определить конструктор с помощью метода __construct.

Методы для классов PHP

Давайте подумаем о методах класса как о функциях, которые выполняют определенные действия, связанные с объектами. В большинстве случаев они используются для доступа и управления свойствами объекта и выполнения связанных операций.

В приведенном выше примере мы определили метод getLastName, который возвращает фамилию, связанную с объектом.

В следующем разделе мы увидим, как создавать объекты класса Employee.

Что такое объект в PHP?

В предыдущем разделе мы обсудили базовую структуру PHP класса. Теперь, когда вы хотите использовать класс, вам нужно его инстанцировать, конечным результатом чего будет объект.  Таким образом, мы можем думать о классе как о проекте, а объект - это реальная вещь, над которой вы можете работать.

В контексте класса Employee, созданного в предыдущем разделе, давайте посмотрим, как создать понятие объекта этого класса.

1
<?php
2
$objEmployee = new Employee('Bob', 'Smith', 30);
3
4
echo $objEmployee->getFirstName(); // print 'Bob'

5
echo $objEmployee->getLastName(); // prints 'Smith'

6
echo $objEmployee->getAge(); // prints '30'

7
?>

Если вы хотите создать понятие объекта любого класса вместе с его именем, нужно использовать ключевое слово new, и в итоге вы получите новое понятие объекта этого класса.

Если класс определил метод  __construct и ему требуются аргументы, вам нужно передать эти аргументы при создании экземпляра объекта. В нашем случае конструктор класса Employee требует три аргумента, и поэтому мы их передали, когда создавали объект $objEmployee. Как мы говорилось ранее, метод __construct вызывается автоматически при инстанциации объекта.

Затем мы вызвали методы класса для объекта $objEmployee, чтобы запечатлить информацию, инициализированную во время создания объекта. Конечно же, вы можете создать несколько объектов одного класса, как это показано в следующем фрагменте.

1
<?php
2
$objEmployeeOne = new Employee('Bob', 'Smith', 30);
3
4
echo $objEmployeeOne->getFirstName(); // prints 'Bob'

5
echo $objEmployeeOne->getLastName(); // prints 'Smith'

6
echo $objEmployeeOne->getAge(); // prints '30'

7
8
$objEmployeeTwo = new Employee('John', 'Smith', 34);
9
10
echo $objEmployeeTwo->getFirstName(); // prints 'John'

11
echo $objEmployeeTwo->getLastName(); // prints 'Smith'

12
echo $objEmployeeTwo->getAge(); // prints '34'

13
?>

Следующее изображение является графическим представлением класса Employee и некоторых его экземпляров.

Object InstantiationObject InstantiationObject Instantiation

Проще говоря, класс - это проект, который вы можете использовать для создания структурированных объектов.

Инкапсуляция

В предыдущем разделе мы обсуждали, как создавать экземпляры объектов класса Employee. Интересно отметить, что сам объект $objEmployee объединяет свойства и методы класса.  Другими словами, он скрывает эти детали от остальной части программы. В мире ООП это называется инкапсуляцией данных.

Инкапсуляция является важным аспектом ООП, позволяющий ограничить доступ к определенным свойствам или методам объекта. А это побуждает нас обсудить другую тему: уровень доступа.

Уровни доступа

Если вы определяете свойство или метод в классе, тогда вы можете объявить, что он имеет один из этих трех уровней доступа - public, private, или protected.

Доступ public

Когда вы объявляете свойство или метод как public, к нему можно получить доступ из любого места вне класса. Значение открытого свойства можно изменить из любого участка вашего кода.

Давайте рассмотрим на пример, чтобы понять как создать уровень публичного доступа.

1
<?php
2
class Person
3
{
4
  public $name;
5
6
  public function getName()
7
  {
8
    return $this->name;
9
  }
10
}
11
12
$person = new Person();
13
$person->name = 'Bob Smith';
14
echo $person->getName(); // prints 'Bob Smith'

15
?>

Как вы видете в приведенном выше примере, мы объявили общедоступное свойство name. Следовательно, вы можете установить его из любого места вне класса, что мы и сделали.

Доступ private

В случае если вы объявляете свойство или метод private, доступ к ним можно получить только из класса. Это означает, что вам нужно определить методы получения и установки, чтобы получить и установить значение этого свойства.

Опять же, давайте пересмотрим предыдущий пример, чтобы понять уровень частного доступа.

1
<?php
2
class Person
3
{
4
  private $name;
5
6
  public function getName()
7
  {
8
    return $this->name;
9
  }
10
11
  public function setName($name)
12
  {
13
    $this->name = $name;
14
  }
15
}
16
17
$person = new Person();
18
$person->name = 'Bob Smith'; // Throws an error

19
$person->setName('Bob Smith');
20
echo $person->getName(); // prints 'Bob Smith'

21
?>

Если вы захотите получить доступ к private свойству вне класса, он выдаст фатальную ошибку Cannot access private property Person::$name. Таким образом, вам нужно установить значение private свойства с помощью метода setter, как мы это cделали с помощью метода setName.

Могут возникать веские причины, из-за которых вы захотите установить private свойство. Например, возможно, для  предпринятия какого-то действия (скажем, обновить базу данных или перерисовать шаблон), если это свойство меняется.  В этом случае вы можете определить метод установки и управление любой специальной логикой для изменения свойства.

Доступ protected 

Наконец, когда вы объявляете свойство или метод protected, к ним может обращаться тот же класс, который их определил, или классы, которые наследуют рассматриваемый класс. Мы обсудим наследование в следующем разделе, поэтому вернемся к уровню защищенного доступа чуть позже.

Наследование

Наследование является важным аспектом парадигмы объектно-ориентированного программирования, которая позволяет наследовать свойства и методы других классов, расширяя их. Класс, который наследуется, называется родительским классом, а класс, который наследует другой класс, называется дочерним классом.  Когда вы создаете экземпляр объекта дочернего класса, он также наследует свойства и методы родительского класса.

Давайте посмотрим на следующий скриншот, чтобы понять концепцию наследования.

InheritanceInheritanceInheritance

В примере выше класс Person является родительским классом, а класс Employee расширяет или наследует класс Person, поэтому и называется дочерним классом.

Давайте попробуем разобраться на реальном примере, чтобы понять, как это работает.

1
<?php
2
class Person
3
{
4
  protected $name;
5
  protected $age;
6
7
  public function getName()
8
  {
9
    return $this->name;
10
  }
11
12
  public function setName($name)
13
  {
14
    $this->name = $name;
15
  }
16
17
  private function callToPrivateNameAndAge()
18
  {
19
    return "{$this->name} is {$this->age} years old.";
20
  }
21
22
  protected function callToProtectedNameAndAge()
23
  {
24
    return "{$this->name} is {$this->age} years old.";
25
  }
26
}
27
28
class Employee extends Person
29
{
30
  private $designation;
31
  private $salary;
32
33
  public function getAge()
34
  {
35
    return $this->age;
36
  }
37
38
  public function setAge($age)
39
  {
40
    $this->age = $age;
41
  }
42
43
  public function getDesignation()
44
  {
45
    return $this->designation;
46
  }
47
48
  public function setDesignation($designation)
49
  {
50
    $this->designation = $designation;
51
  }
52
53
  public function getSalary()
54
  {
55
    return $this->salary;
56
  }
57
58
  public function setSalary($salary)
59
  {
60
    $this->salary = $salary;
61
  }
62
63
  public function getNameAndAge()
64
  {
65
    return $this->callToProtectedNameAndAge();
66
  }
67
}
68
69
$employee = new Employee();
70
71
$employee->setName('Bob Smith');
72
$employee->setAge(30);
73
$employee->setDesignation('Software Engineer');
74
$employee->setSalary('30K');
75
76
echo $employee->getName(); // prints 'Bob Smith'

77
echo $employee->getAge(); // prints '30'

78
echo $employee->getDesignation(); // prints 'Software Engineer'

79
echo $employee->getSalary(); // prints '30K'

80
echo $employee->getNameAndAge(); // prints 'Bob Smith is 30 years old.'

81
echo $employee->callToPrivateNameAndAge(); // produces 'Fatal Error'

82
?>

Здесь важно отметить, что класс Employee использовал для наследования класса Person ключевое слово extends. Теперь класс Employee может получить доступ ко всем свойствам и методам класса Person, объявленные как public или protected. (Он не может получить доступ к ntv, которые объявлены как private.)

В примере выше объект $employee может получить доступ к методам getName и setName, которые определены в классе Person, поскольку они объявлены как public.

Затем мы обратились к методу callToProtectedNameAndAge, используя метод getNameAndAge, определенный в классе Employee, поскольку он объявлен как protected. Наконец, объект $employee не может получить доступ к методу callToPrivateNameAndAge класса Person, поскольку он объявлен как private.

С другой стороны, вы можете использовать объект $employee для установки свойства age класса Person, как мы это делали в методе setAge, который определен в классе Employee, поскольку свойство age объявлено как protected.

И так, это было краткое введение в наследование. Оно помогает сократить дублирование кода и, следовательно, способствует его повторному использованию.

Полиморфизм

Полиморфизм - еще одна важная концепция в мире объектно-ориентированного программирования, которая относится к способности по-разному обрабатывать объекты в зависимости от их типов данных.

Например, в контексте наследования, если дочерний класс хочет изменить поведение метода родительского класса, он может переопределить этот метод.  Это называется переопределением метода. Давайте быстро рассмотрим реальный пример, чтобы понять концепцию переопределения метода.

1
<?php
2
class Message
3
{
4
  public function formatMessage($message)
5
  {
6
    return printf("<i>%s</i>", $message);
7
  }
8
}
9
10
class BoldMessage extends Message
11
{
12
  public function formatMessage($message)
13
  {
14
    return printf("<b>%s</b>", $message);
15
  }
16
}
17
18
$message = new Message();
19
$message->formatMessage('Hello World'); // prints '<i>Hello World</i>'

20
21
$message = new BoldMessage();
22
$message->formatMessage('Hello World'); // prints '<b>Hello World</b>'

23
?>

Как видите, мы изменили поведение метода formatMessage, переопределив его в классе BoldMessage. Важно то, что сообщение форматируется по-разному в зависимости от типа объекта, будь то экземпляр родительского или дочернего класса.

(Некоторые объектно-ориентированные языки также имеют своего рода перезагрузку методов, которая позволяет определять несколько методов класса с одним и тем же именем, но с разным количеством аргументов. Это не поддерживается напрямую в PHP, но существуют несколько обходных путей для достижения аналогичной функциональности.)

Итоги

Объектно-ориентированное программирование является обширной темой, и мы лишь поверхностно рассмотрели его сложность. Я очень надеюсь, что этот урок помог вам освоить основы ООП и побудило продолжить изучение более сложных тем по ООП.

Независимо от технологии, с которой вы работаете, объектно-ориентированное программирование является важным аспектом в разработке приложений. Сегодня в контексте PHP мы обсудили несколько базовых концепций ООП, а также использовали возможность предоставить несколько реальных примеров.

Не стесняйтесь размещать свои просьбы в комментариях ниже!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.