Основы ООП

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





Читайте также:



14 Ответов на “Основы ООП”

  1. Прохожый

    Спасибо, классно написано.

  2. novice

    Всегда пожалуйста :)

  3. не работает один из ваших примеров, пишет
    “Parse error: syntax error, unexpected T_STRING, expecting T_VARIABLE in Z:\***\ex2.php on line 4

    myMethod(); // можно
    $obj->myMethod2(); // нельзя! Ошибка доступа
    $obj->myMethod3(); // нельзя! Ошибка доступа
    ?>

    если заменить на function myMethod() - то проблем не возникает….можно уточнить что именно я делаю не так)?

  4. novice

    Да, спасибо за замечание. Была моя ошибка в тексте, которая уже исправлена. Нужно писать public function myMethod(), т.е. не хватает ключевого слова function.

  5. Leech

    Спасибо огромное. Я кинестет и для понимания мне нужны примеры, простые такие примеры с комментариями по строкам. У Вас как раз все как надо.

    Еще раз СПАСИБО !!!

  6. Михаил

    Цитата:
    Автомобиль ЗАЗ 968М - он же запорожец :) - принадлежит к классу легковых автомобилей. Или Subaru Forester - тоже принадлежит к классу легковых авто. Разница между запорожцем и субару конечно существенна, но на самом деле они имеют много общего :) - те же цвет кузова, расход топлива и т.д. Поэтому эти две контрастно-различающиеся машины можно выделить в один класс - класс легковых авто.

    Эти две машины являются двумя совершенно разными объектами. Понятно, что они сильно различаются. И пусть в меня кинет камень тот, кто со мной не согласится :)

    Конец цитаты

    Теперь кидаю камень:

    ЗАЗ 968М и Subaru Forester - это никакие не объекты, а просто подклассы данного класса. Объектами будут “вон тот вот Запорожец” или “Субару моего друга”

  7. novice

    Ну конечно! Считай, что я это имел в виду 😉

  8. Jenia

    Написано интересно, но как для основ ООП - слишком сложно, если ты раньше никогда не сталкивался с ООП - то эта статья только запутает.

  9. kononj

    Да уж доходчивей и проще и написать-то невозможно.
    Я вот начал изучать ООП и эта статья, как раз как краткий карманный справочник. Спасибо!

  10. Andrey

    Хорошая статья. Спасибо.

  11. Дима

    Отлично. Понял статические методы и свойства…

  12. Андрей

    Спасибо за статью!

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

  13. улыбайтесь, это всех раздражает

    )))))))) )))))))))))))))) )))))))))))) )))))))))) ))))))))) ))))))))))))) )))))))))))) ))))))))))))) ))))))))))))) )))))))!

  14. Не плохая статья добавлю в закладки для подробного анализа.


© Copyright. . I-Novice. All Rights Reserved. Terms | Site Map