Основы ООП
Мне кажется, что уже пора переходить к более серьезным вещам в веб-программировании, и начать я хотел бы с объектно-ориентированных возможностей языка PHP5. Но прежде, чем перейти к этой теме, нам нужно разъяснить для себя некоторые понятия ООП (объектно-ориентированного программирования). |
Понятия
Начнем с понятия класса. Класс - это некая структура данных и методов, которая позволяет описать некоторый объект (кстати, объект - это уже другое понятие). А если говорить простыми словами, то можно привести наглядный пример.
Рассмотрим автомобиль. У автомобиля есть свойства и есть функции, которые он может выполнять. Среди свойств можно выделить, например, расход топлива, цвет кузова, объем двигателя, тип кузова, тип коробки передач и т.д. Основные функции автомобиля - ехать вперед/назад, повернуть налево/направо и т.д.
Автомобиль ЗАЗ 968М - он же запорожец - принадлежит к классу легковых автомобилей. Или Subaru Forester - тоже принадлежит к классу легковых авто. Разница между запорожцем и субару конечно существенна, но на самом деле они имеют много общего - те же цвет кузова, расход топлива и т.д. Поэтому эти две контрастно-различающиеся машины можно выделить в один класс - класс легковых авто.
Эти две машины являются двумя совершенно разными объектами. Понятно, что они сильно различаются. И пусть в меня кинет камень тот, кто со мной не согласится Нашел с чем субару сравнивать - скажете Вы
Вот я и привел пример, что такое класс, а что такое объект.
Свойства и методы
Теперь про то, как описывается класс в PHP на примере описания класса автомобилей:
<? class Car { protected $bodyColor; // свойство «цвет кузова» protected $fuelRate; // свойство «расход топлива» protected $engineVolume; // свойство «объем двигателя» public function accelerate() { // добавить газу // … } public function slowdown() { // тормозить // … } } ?>
Так я попытался описать класс всех автомобилей. Правда я тут очень урезал возможности всех машин, но для примера достаточно.
Модификаторы доступа
Теперь поговорим про модификаторы доступа. Они бывают трех видов: public, protected и private. public - значит, что свойство или метод с таким модификатором доступен извне класса везде, где программисту захочется. Этот модификатор ставится по умолчанию, если не определен другой. protected и private - означают, что метод или свойство доступно только внутри этого класса. protected и private различаются только в случае наследования классов, о чем мы поговорим в отдельной статье.
<? class MyClass { public function myMethod() { } protected function myMethod2() { } private function myMethod3() { } } $obj = new MyClass; $obj->myMethod(); // можно $obj->myMethod2(); // нельзя! Ошибка доступа $obj->myMethod3(); // нельзя! Ошибка доступа ?>
Ключевым словом new я сказал PHP создать объект класса MyClass и сохранить его в переменной $obj. Затем я попытался вызвать открытый метод myMethod и этот вызов у меня успешно сработал. Потом я попытался обратиться к защищенным методам класса myMethod2 и myMethod3, но пхп стал ругаться и прервал выполнение скрипта. А зачем тогда нужны защищенные методы, если их нельзя вызывать?
Неее, вызывать их на самом деле можно, только не извне класса, а внутри его:
<? class MyClass { public function myMethod() { $this->myMethod2(); $this->myMethod3(); } protected function myMethod2() { $this->myMethod3(); } private function myMethod3() { } } ?>
То же самое относится и к свойствам класса: обращаться к защищенным свойствам можно только внутри самого класса либо в классе-наследнике, если свойство не обозначено как private. О классах наследниках и о наследовании вообще мы поговорим в отдельной статье.
Указатель this
А что такое $this? А это указатель на самого себя. Он может использоваться внутри самого класса, чтобы обращаться к своим же методам и свойствам.
Конструкторы и деструкторы
Любой объект в PHP всегда создается в памяти, а затем рано или поздно уничтожается. За это отвечают специальные невидимые методы класса - конструкторы и деструкторы. Но невидимы они только если мы их сами не определим:
<? class MyClass { function __construct() { echo "Запущен конструктор"; } function __destruct() { echo "Запущен деструктор"; } } $obj = new MyClass(); // Выводит "Запущен конструктор" unset($obj); // Выводит "Запущен деструктор" ?>
Таким образом, ключевое слово new создает новый объект в памяти, вызывая перед этим конструктор этого объекта, в котором можно присвоить каким-то свойствам объекта какие-то значения или еще что-нить полезное/нужное сделать. Замечу, что конструктор не может возвращать значение, как обыкновенный метод класса, т.е. return в нем писать нельзя. Но конструктор может принимать параметры, чего не скажешь о деструкторе, который возвращать значения не может, и принимать параметры тоже не в состоянии:
<? class MyClass { function __construct($param) { echo $param; } function __destruct() { echo "Запущен деструктор"; } } $obj = new MyClass("123"); // Выводит "123" unset($obj); // Выводит "Запущен деструктор" ?>
Константы класса
В классе может быть какое-то константное свойство, которое никогда не изменяется:
<? class MyClass { const CONSTANT = "константа класса"; } echo MyClass::CONSTANT; // Выводит "константа класса" ?>
Статические элементы класса
<? class MyClass { static $property = 1; } echo MyClass::$property; // Выводит 1 ?>
Cтатические свойства класса едины для всего класса и не могут принадлежать ни одному из объектов класса. Изменение такого свойства в одном из методов любого объекта приведет к его изменению для всех остальных объектов этого класса. Кроме этого, можно обратиться к такому свойству вне контекста объекта, т.е. применяя двоеточия, как показано в примере.
Также мы можем объявить статическими не только свойства класса, но и его методы:
<? class MyClass { static function statFunc() { echo "статический метод"; } } MyClass::statFunc(); // Выводит "статический метод" ?>
Статические методы класса тоже используются вне контекста объекта, т.е. не нужно создавать объект, чтобы использовать такой метод. Достаточно вызвать его, как показано в примере. Только здесь надо сделать одну небольшую оговорку. Вспомним указатель this. Так вот его нельзя использовать внутри статического метода класса, потому что указатель this - это указатель на текущий объект класса, а для вызова такого метода объект не создается. Значит, указывать не на что.
Спасибо, классно написано.
Всегда пожалуйста
не работает один из ваших примеров, пишет
“Parse error: syntax error, unexpected T_STRING, expecting T_VARIABLE in Z:\***\ex2.php on line 4
”
myMethod(); // можно
$obj->myMethod2(); // нельзя! Ошибка доступа
$obj->myMethod3(); // нельзя! Ошибка доступа
?>
если заменить на function myMethod() - то проблем не возникает….можно уточнить что именно я делаю не так)?
Да, спасибо за замечание. Была моя ошибка в тексте, которая уже исправлена. Нужно писать public function myMethod(), т.е. не хватает ключевого слова function.
Спасибо огромное. Я кинестет и для понимания мне нужны примеры, простые такие примеры с комментариями по строкам. У Вас как раз все как надо.
Еще раз СПАСИБО !!!
Цитата:
Автомобиль ЗАЗ 968М - он же запорожец - принадлежит к классу легковых автомобилей. Или Subaru Forester - тоже принадлежит к классу легковых авто. Разница между запорожцем и субару конечно существенна, но на самом деле они имеют много общего - те же цвет кузова, расход топлива и т.д. Поэтому эти две контрастно-различающиеся машины можно выделить в один класс - класс легковых авто.
Эти две машины являются двумя совершенно разными объектами. Понятно, что они сильно различаются. И пусть в меня кинет камень тот, кто со мной не согласится
Конец цитаты
Теперь кидаю камень:
ЗАЗ 968М и Subaru Forester - это никакие не объекты, а просто подклассы данного класса. Объектами будут “вон тот вот Запорожец” или “Субару моего друга”
Ну конечно! Считай, что я это имел в виду 😉
Написано интересно, но как для основ ООП - слишком сложно, если ты раньше никогда не сталкивался с ООП - то эта статья только запутает.
Да уж доходчивей и проще и написать-то невозможно.
Я вот начал изучать ООП и эта статья, как раз как краткий карманный справочник. Спасибо!
Хорошая статья. Спасибо.
Отлично. Понял статические методы и свойства…
Спасибо за статью!
Вот я только ни как не могу вехать - для чего нужны статические методы и свойства? Когда их стоит применять, в чем их польза и сила (в сравнение с обычными методами и свойствами объекта). Вообще, когда обращаешься к к статическому свойству (методу) через :: то происходит создание в памяти нового объекта или нет (читай может они менее ресурсоемки в этом и сила)?
)))))))) )))))))))))))))) )))))))))))) )))))))))) ))))))))) ))))))))))))) )))))))))))) ))))))))))))) ))))))))))))) )))))))!
Не плохая статья добавлю в закладки для подробного анализа.