PHP ООП. Урок 1: Обьекты и классы
PHP ООП. Урок 1: Обьекты и классы.
О курсе
Продолжаем изучать PHP и в этот раз будем изучать объектно-ориентированное программирование на PHP. Само по себе объектно-ориентированное программирование не несет никакой магии. И технически, все что при помощи ООП написано, можно реализовать и с помощью функций. ООП придумали для удобства программирования. Нужно не зубрить термины используемые в ООП, а понять их преимущества использования. Попробуем выяснить, что же побудило программистов придумать себе ООП.Типы структуры
Сам по себе компьютер не разбирается в типах вообще. Он обращает внимание только на их размер - количество байтов.
Люди придумали типы исходя из того, что они вводят в компьютер и что он им выводит.
Обычно это да или нет (логический), числа (в том числе с плавающей точкой - для финансовых и научных данных) и строки.
Причем строка не является самостоятельным типом данных, строка - это массив значений типа char (символ), который в зависимости от кодировки представлен одним или двумя байтами. Строки оканчиваются нулевым символом (\0).
Так вот, когда таких простых типов в исходном коде программы становится много, то может появиться путаница и возникает желание эти данные логически объединить (структуризировать).
Для этого и придумали структуры.
Образно говоря структура - это такой кусочек кода, в котором объявляются переменные, но кусочек имеет имя, по которому можно найти эти переменные.
Например (это код на С т.к. в PHP структур нет):
struct Person {
unsigned int age;
char[80] first_name; /* string */
char[82] last_name; /* string */
int balance;
};
Здесь мы объявили четыре переменные (возраст, имя, фамилия, баланс), обьединенных в структуру под названием Person. Таким образом даже логически становиться погнятно, что речь идет о каком то человеке (пользователе, аккаунте, счете и.т.п).
Это гораздо удобнее, нежели объявлять десятки и сотни переменных "в одной куче".
После того, как структуры возымели успех у программистов, то подумали, раз с переменными все так хорошо, не плохо бы также структуризировать и функции.
Классы
Поскольку от функций без данных толку мало, то решили не изобретать специальный спецификатор (хотя в результате он все же появился: interface), а засунуть функции прямо в структуры.
Назвали это творение более грандиозно: Класс. Имеется ввиду не школьный класс, а некий набор сущностей, объединенных общими признаками.
Таким образом, класс объединять себе описания данных, а также действий над этими данными.
class Person {
public $age;
public $first_name;
public $last_name;
public $balance = 0;
}
По сути в примере на PHP мы сделали то же что и при рассмотрении структур. Однако теперь это класс с четырьмя переменными.
С помощью спецификатора public мы сообщаем, что к ним можно обращаться из-вне класса.
Т.е. из глобальной области видимости или из других классов.
Однако для того, чтобы мы могли обратиться к переменным класса, нужно сначала создать его обобьет, а затем инициализировать данные.
Дело в том, что класс сам по себе не обладает памятью и не может хранить данные (кроме статических переменных).
Класс представляет только описание типа, а объекты - переменные этого типа нужно создать, чтобы воспользоваться возможностями предоставляемые классом.
Мы так и сделаем:
$p1 = new Person();
$p1->age = 26;
$p1->first_name = "Руслан";
$p1->last_name = "Дорофеев";
$p1->balance = "100 GBG";
Оператор new как раз и создает обобьет. Он сообщает, что нужно выделить место в памяти для хранения данных, описанных классом Person. А затем присваивает ссылку переменной $p1 на это место в памяти.
Доступ к свойствам и функциям (методам) объекта мы получаем с помощью оператора (->). Он также напоминает нам, что мы работаем не с самими данными, а с ссылками на эти данные (адресами) в памяти.
Обычно классы создаются, чтобы на их основе создавать не один, а много объектов. На то они и классы.
Давайте создадим еще один:
$p2 = new Person();
$p2->first_name = "Боб";
$p2->last_name = "Губка";
Как видите не обязательно инициализировать все переменные.
Теперь можно вывести и посмотреть, что в разных объектах разные значения:
echo $p1->first_name; // Руслан
echo $p2->first_name; // Боб
Как видите у разных объектов одни те же свойства хранят разные значения.
Все верно, так как p1 и p2 указывают на разные места в памяти (ссылаются на разные объекты класса Person).
Следовательно, если мы сделаем подобное присваивание:
$my_var = $p2;
$my_var->first_name = "Майк";
То и $p2 и $my_var будут ссылаться на одной то же место в памяти и мы перезапишем значение переменной first_name именно в памяти, на которую указывают эти объекты.
Получается $my_var = $p2;
просто сообщает $my_var адрес из переменной $p1, но не копирует данные объекта (чтобы скопировать данные из одного объекта в другой используется операция clone).
Т.о. теперь
echo $my_var->first_name; // Майк
echo $p2->first_name; // Майк