Основы ООП
![]() |
Мне кажется, что уже пора переходить к более серьезным вещам в веб-программировании, и начать я хотел бы с объектно-ориентированных возможностей языка 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 – это указатель на текущий объект класса, а для вызова такого метода объект не создается. Значит, указывать не на что.






Июль 14th, 2008
Спасибо, классно написано.
Июль 15th, 2008
Всегда пожалуйста
Январь 8th, 2009
не работает один из ваших примеров, пишет
“Parse error: syntax error, unexpected T_STRING, expecting T_VARIABLE in Z:\***\ex2.php on line 4
”
myMethod(); // можно
$obj->myMethod2(); // нельзя! Ошибка доступа
$obj->myMethod3(); // нельзя! Ошибка доступа
?>
если заменить на function myMethod() – то проблем не возникает….можно уточнить что именно я делаю не так)?
Январь 8th, 2009
Да, спасибо за замечание. Была моя ошибка в тексте, которая уже исправлена. Нужно писать public function myMethod(), т.е. не хватает ключевого слова function.
Февраль 20th, 2009
Спасибо огромное. Я кинестет и для понимания мне нужны примеры, простые такие примеры с комментариями по строкам. У Вас как раз все как надо.
Еще раз СПАСИБО !!!
Май 18th, 2009
Цитата:
– принадлежит к классу легковых автомобилей. Или Subaru Forester – тоже принадлежит к классу легковых авто. Разница между запорожцем и субару конечно существенна, но на самом деле они имеют много общего
– те же цвет кузова, расход топлива и т.д. Поэтому эти две контрастно-различающиеся машины можно выделить в один класс – класс легковых авто.
Автомобиль ЗАЗ 968М – он же запорожец
Эти две машины являются двумя совершенно разными объектами. Понятно, что они сильно различаются. И пусть в меня кинет камень тот, кто со мной не согласится
Конец цитаты
Теперь кидаю камень:
ЗАЗ 968М и Subaru Forester – это никакие не объекты, а просто подклассы данного класса. Объектами будут “вон тот вот Запорожец” или “Субару моего друга”
Май 18th, 2009
Ну конечно! Считай, что я это имел в виду
Июль 8th, 2009
Написано интересно, но как для основ ООП – слишком сложно, если ты раньше никогда не сталкивался с ООП – то эта статья только запутает.
Июль 24th, 2009
Да уж доходчивей и проще и написать-то невозможно.
Я вот начал изучать ООП и эта статья, как раз как краткий карманный справочник. Спасибо!
Июль 24th, 2009
Хорошая статья. Спасибо.
Январь 30th, 2010
Отлично. Понял статические методы и свойства…
Февраль 21st, 2010
Спасибо за статью!
Вот я только ни как не могу вехать – для чего нужны статические методы и свойства? Когда их стоит применять, в чем их польза и сила (в сравнение с обычными методами и свойствами объекта). Вообще, когда обращаешься к к статическому свойству (методу) через :: то происходит создание в памяти нового объекта или нет (читай может они менее ресурсоемки в этом и сила)?
Апрель 18th, 2010
)))))))) )))))))))))))))) )))))))))))) )))))))))) ))))))))) ))))))))))))) )))))))))))) ))))))))))))) ))))))))))))) )))))))!
Май 12th, 2011
Не плохая статья добавлю в закладки для подробного анализа.