Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
Итак, что такое Объектно ориентированное программирование. Вам скорее всего известно, что часто повторяющиеся участки кода, которые приходится выполнять могократно с различными параметрами, очень удобно оформить в виде функции. А теперь представьте себе, что вы, скажем, моделируете движение автомобилей по дороге. Каждый автомобиль движется, обладает своими характеристиками, изменяющимися в каждый момент времени. Без применения ООП, вы бы создали отдельные массивы свойств, применяли бы к ним свои функции. Терпимо. И вдруг на горизонте появляется грузовик. У него, в отличие от других, есть кузов. А вон старенький Запорожец. У него нет магнитолы. Таким образом, мы уже не можем сказать, что первый элемент каждого массива относится к первой машине, второй - ко второй и так далее. Где-то что-то своё. Да, еще и память же надо подо всё это выделить, хотя, в PHP нет этой проблемы. Мы можем придумать различные ухищрения, организовать еще кучу массивов и добиться результата, но получатеся сложно и изменения отслеживать и вносить в такой код будет неприятно и сложно. Нам гораздо удебнее сделать все эти автомобили объектами. Объет - это переменная особого типа. Этот тип называтся класом. Класс включает в себя войства (цвет, вес) и методы (передвинуться, побибикать). Свойства - это переменные; методы - функции.
Собрав свойства и методы объекта в одну структуру данных, нам не только будет удобно обслуживать такой код, мы сможем использовать наш класс и в других проектах. Но и это еще не всё. Как пишут в учебниках, ООП основано на трёх слонах: инкапсуляция, наследование и полиморфизм.
Прежде, чем дать определения, пора уже начинать четко представлять, о чем пойдет речь, поэтому пример.
Здесь мы описали класс my_first. В нем свойтсво "prop" и метод set_prop, который задает значение свойству. Чтобы создать объект, в PHP используется оператор new. Из кода видно и как работает метод, и как обратиться к свойтсву. Внутри класса используется переменная $this. Через нее мы обращаемся к свойствам и методам конкретного объекта.
Интересное cлово public. Кроме него есть еще private и protected. Эти слова мы можем использовать перед описанием свойтва или метода, и означают они следующее: public - свойство (или метод) доступен на прямую из любого места программы. private. - свойство (или метод) доступен только методам текущего класса. protected - свойство (или метод) доступен только классу и его наследникам (об этом чуть позже).
Если ни одно из этих слов не указано, то по умолчанию уровень доступа будет public.
Посмотрим пример:
$this->priv;// А тут мы ничего не увидим: это свойство родительского класса приватное, и здесь оно не видно.
}
}
$obj=new first;
echo$obj->pub,// 3
$obj->prot,// Ошибка: не удается получить доступ к защищенному свойтсву
$obj->priv;// Ошибка: не удается получить доступ к приватному свойтсву
?>
Теперь те самые три слона. Инкапсуляция - такое замечательное свойство, которое не дает менять на прямую определенные свойства объекта, а позволяет это сделать только специально написанными методами самого класса. Это позволяет избежать при грамотной реализации некорректных значений в свойствах класса. Опишем объект Автомобиль и применим в нём инкапсуляцию
В объектах этого класса мы не сможем задать скорость, напрямую присвоив ей значение. Для этих целей нам надо будет использовать интерфейсный метод set_speed(), в котором осуществится проверка переданного значения и гарантируется его корректность.
Наследование. Новый класс представляет собой какой-либо существующий, но в него что-то добавлено или что-то изменено.
Объекты класса грузовик имеют свойства Цвет и Скорость родительского класса, переопределенное свойство Тип и новове свойство Кузов. Метод set_speed переопределен: теперь максимальная скорость составляет 12 км/ч. Метод beep также унаследован грузовиком у болида Формулы-1.
Полиморфизм - это такое немного необычное проявление наследования. Проявляетсяон в том, что функция, объявленная в родительском классе начинает работать с данными дочернего класса.
В 3м примере унаследованная функция f2 из первого класса вызвала внутри себя функцию f1 дочернего класса.
Конструктор и деструктор.
Эти методы вызываются автоматически. Первый при создании объекта, второй при удалении. Явно их вызывать не нужно. Конструктор можно использовать для инициализации свойств, например. Деструктор - для освобождения ресурсов. Эти методы всегда должны иметь уровень доступа public. Констуктор описывается следующм образом: function __construct(); деструктор: function __destruct(). В начале два прочерка.
Абстрактнае классы и методы.
Абстрактные методы - такие методы, которые объявлены в класе, но описание их пустое. Класс, содержащий хотя бы один такой метод - абстрактный, и должен быть объявлен с использванием волшебного слова abstract:
Создать объект такого класса нельзя, и используются такие классы только для наследования. Не абстракнтые методы в абстрактном классе присутствовать могут.
Если в абстрактном классе нет ни одного свойства, а методы его только абстрактные, то такой класс называется интерфейсом. Для него в PHP существует специальное слово:
Еще надо рассказать о слове final. Этим словом обозначаются финальные методы и классы. Финальный - это такой, который не может быть переопределен в наследниках. Ну и отсюда ясно, что наследовать от финального класса нельзя. Вот так.
Статические свойства и методы.
Чтобы сделать свойство или метод статическим, надо предварить его описание свойством static:
К статическим методам и свойствам можно обращаться, не создавая объект класса. Например, мы описали какой-нибудь класс математических методов. Объект нам не нужен, а вот функции используем.
Чтобы внутри метода класса обратиться к его статическоу члену, используется волшебное слово self::. К родительскому классу можно обратиться, использовав слово parent::. К произвольному классу можно обратиться, использовав его имя: classname::.
Константы, как видно из примера, тоже являются статическими методами.
Клонирование объектов.
Иногда бывает, что вам нужно скопировать объект. И после этого часть свойств надо изменить. Причем это всегда одни и те же свойства и принимают одни и те же значения после копирования. В PHP есть для этого механизм клонирования.
Клонирование объекта выполняется так:
Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006 Откуда: Israel
Помог: 3 раз(а)
Версия 2
--
ООП с начала
ООП = Объектно Ориентировочное Программирование = Object Oriented Programming
Подход в программировании, рассматривающий все в виде объектов.
Объект = класс это такая единица чего нибудь. К примеру Зверь.
Объект умеет что-то делать ( издавать звук, кушать, передвигаться ) = Методы
и имеет какие-то свойства ( Количество задних ног, диаметр глазных яблок ) = Свойства
class Beast // Ключевое слово class и название класса.
{
// Свойство "любимое_блюдо"
$favorite_meal='Блины с икрой';
// Метод "ешь!"
function eat(){echo$favorite_meal,' - ням ням.';}
}
Вероятно, когда мы заведем себе питомца крокодила данди, нам захочется его покормить.
Для этого будет достаточно вызвать метод "А ну ешь!". А сам метод должен быть для нас доступен. Простыми словами Данди должен разрешить нам -его кормить.
Здесь вступают в силу три режима видимости:
public - свойство (или метод) доступен на прямую из любого места программы.
Вызвать метод или узнать значение свойства можно где угодно.
private - свойство (или метод) доступен только методам текущего класса.
Вызвать метод или манипулировать свойством можно только из другого метода этого же класса.
protected - свойство (или метод) доступен только классу и его наследникам (об этом чуть позже).
Если режим видимости не указан - применяется значение public по умолчанию.
--
Для того, чтобы создать себе зверька = экземпляр класса, мы пользуемся ключевым словом new;
Этот код выдаст ошибку в последней строчке. Данное свойство закрыто для внешнего мира ключевым словом private;
Другие крутые ключевые слова и знаки
Предположим у нас есть класс для работы с почтой. Он умеет читать почту, посылать всех подальше за Вас и между тем имеет классный метод, определяющий название дня по дате.
Наш метод getDateName($date) не работает ни с какими почтовыми данными.
Для того, чтобы вызвать этот метод, нам нужно создать экземпляр класса, загрузить все его методы и свойства в память, а после чего вызывать уже метод.
$mailClass = new Mail;
$mailClass->getDateName($somedate);
На самом деле здесь можно сэкономить. Выиграть в памяти и производительности поможет оператор ::. В профессиональном жаргоне называется - паамаим некудотаим.
Этот оператор позволяет обращаться к методам и свойствам класса не создавая его копию в памяти.
Mail::getDateName($somedate);
название класса::название метода или свойства.
--
Также науке известно ключевое слово static.
Слово это ставится сразу после метки видимости ( public, private, protected )
и то, не всегда.
Те, кто читал урок номер 2 про переменные и то, как они хранятся в памяти - знают,
что интерпретатор создает связку между названием переменной и физическим адресом в оперативной памяти.
Каждый раз когда мы создаем экземпляр класса, под все свойства выделяется новое место в памяти. Когда какой-то функции мы передаем значение по ссылке, мы фактически передаем функции адрес в памяти с которым она будет работать.
Ключевое слово static указывает на то, что свойство или метод всех экземпляров будет указывать на определенное место в памяти, а не создавать копии.
----- Truly yours, Sasha.
valenok
Отправлено: 23 Октября, 2009 - 15:49:52
Здесь могла бы быть ваша реклама
Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006 Откуда: Israel
Помог: 3 раз(а)
Авто-загрузка - Autoloading
Многие программисты сохраняют по одному классу в .php файле. Такой подход весьма удобен, но вынуждает писать большое количество инклудов в начале скрипта для подключения всего нужного.
Начиная с PHP5 вы можете создать функцию (не метод какого либо класса, а самую обычную функцию ) с ключевым названием __autoload, принимающая в качестве аргумента название класса.
Эта функция автоматически будет вызываться при попытке создания экземпляра доселе не объявленного класса.
функция __autoload вызовется сама с параметром MyClass1 если ранее вы нигде не объявляли class MyClass1 {..}
Кроме того, MyClass1 можно объявить в самой функции.
Замечу что
1. Автозагрузка __autoloading не доступна в php-cli (php command line interpretator)
2. Обработка ошибок выброшенных throw не может быть поймана catch внутри данной функции
PHP умеет вызывать определенный метод класса при создании экземпляра этого класса = Конструктор
и вызывать другой метод при удалении экземпляра класса = Деструктор
Эти функции именуются ключевыми словами __construct и __destruct
Вы наверное заметили разницу между тем, как мы создавали экземпляры класса ранее и как мы это сделали сейчас.
Ранее мы просто вызывали new ClassName;
На этот раз мы его вызвали с параметрами в скобочках new ClassName(...);
Эти параметры и передаются конструктору, который вызывается автоматически.
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
Магические методы.
Встречаются такие события, которые нам было-бы интересно отслеживать,
к примеру обращения к несуществующим методам и свойствам, созданиям нового экземпляра класса и несколько других событий.
Для этого PHP предоставляет пару специальных методов класса:
_call
Если вы хотите отслеживать и обрабатывать попытки вызова несуществующих методов класса,
можете использовать магический метод __call().
__set и __get
Эти методы аналогичны предыдущему, но применяются к свойствам класса.
Первый срабатывает при попытке записи несуществующему свойству,
второй при обращении к несуществующему свойству.
__sleep и __wakeup (> php 5.3.0)
При сериализации объекта вызывается __sleep()
При обратной процедуре объекта вызывается __wakeup()
Предназначение функции __sleep() это очистка объекта от ненужного мусора перед его сохранением
или игнорированием свойств не предназначенных для сохранения.
Функция должна возвращать массив с именами свойств предназначенных для сохранения. Если функция ничего не возвращает - соответственно никакие свойства функции и не сохраняются.
У восстановленного класса переменная $g будет отсутствовать, так как он сохранена не была.
Штука это новая и в старых версиях PHP (до 5.3.0) отсутсвует
__toString
Этот метод определяется в классе, когда к нему планируется обращаться как к строке: вывод на экран, конкатенация и т. д..
Покинул форум
Сообщений всего: 35
Дата рег-ции: Март 2008
Помог: 0 раз(а)
Спасибо, очень нужная тема.
Вот только код, иллюстрирующий полиморфизм, не работает. У меня выводит Fatal error: Call to undefined function f1() in C:\del on line 4
Ch_chov
Отправлено: 31 Декабря, 2009 - 20:45:03
Постоянный участник
Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008 Откуда: из города
Помог: 90 раз(а)
Ага, f1() заменить на $this->f1()
movEAX
Отправлено: 31 Декабря, 2009 - 22:15:22
Частый посетитель
Покинул форум
Сообщений всего: 750
Дата рег-ции: Авг. 2009
Благодря namespaces не возникает конфликта при объявлении классов с одинаковыми именами, ибо первый класс находиться в пространстве имен mysql, а второй в mssql.
Многие, наверно, помнят о такой фишке, когда в переменную можно занести имя функции, а потом вызвать эту функцию добавив к переменной круглые скобки. Так вот, теперь это можно вытворять с классами!
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.