На главную Назад
Добро пожаловать, уважаемый посетитель!

 

ГЛАВА 6

Объектно-ориентированные возможности РНР

Если выориентируетесь в современных технологияхпрограммирования, объектно-ориентированноепрограммирование (ООП) наверняка являетсячастью вашей повседневной работы. Если жевы принадлежите к числу новичков в областиООП, после чтения этой главы и рассмотрениянескольких примеров программированиепредстанет перед вами совсем в новом свете.Эта глава посвящена технологии ООП и еереализации в РНР. В ней описан весьнеобходимый синтаксис и приводятся примеры,которые позволят вам заняться созданиемобъектно-ориентированных приложений.

СтратегиюООП лучше всего описать как смещениеприоритетов в процессе программирования отфункциональности приложения к структурамданных. Это позволяет программистумоделировать в создаваемых приложенияхреальные объекты и ситуации. Технология ООПобладает тремя главными преимуществами:

  • она простадля понимания - ООП позволяет мыслитькатегориями повседневных объектов;
  • повышеннонадежна и проста для сопровождения -правильное проектирование обеспечиваетпростоту расширения и модификацииобъектно-ориентированных программ.Модульная структура позволяет вноситьнезависимые изменения в разные частипрограммы, сводя к минимуму риск ошибокпрограммирования;
  • ускоряетцикл разработки - модульность и здесьиграет важную роль, поскольку различныекомпоненты ОО-программ можно легкоиспользовать в других программах, чтоуменьшает избыточность,кода и снижаетриск внесения ошибок при копировании.

СпецификаООП заметно повышает эффективность трудапрограммистов и позволяет им создаватьболее мощные, масштабируемые и эффективныеприложения. Многие преимущества ООПобусловлены одним из его фундаментальныхпринципов - инкапсуляцией.Инкапсуляцией называетсявключение различных мелких элементов вболее крупный объект, в результате чегопрограммист работает непосредственно сэтим объектом. Это приводит к упрощениюпрограммы, поскольку из нее исключаютсявторостепенные детали.

Инкапсуляциюможно сравнить с работой автомобиля с точкизрения типичного водителя. Многие водителине разбираются в подробностях внутреннегоустройства машины, но при этом управляют еюименно так, как было задумано. Пусть они незнают, как устроен двигатель, тормоз илирулевое управление, - существуетспециальный интерфейс, которыйавтоматизирует и упрощает эти сложныеоперации. Сказанное также относится кинкапсуляции и ООП - многие подробности <внутреннегоустройства> скрываются от пользователя,что позволяет ему сосредоточиться нарешении конкретных задач. В ООП этавозможность обеспечивается классами,объектами и различными средствамивыражения иерархических связей между ними (классыи объекты рассматриваются ниже).

РНР и ООП

Хотя РНРобладает общими объектно-ориентированнымивозможностями, он не является полноценнымОО-языком (например, таким, как C++ или Java). Вчастности, в РНР не поддерживаютсяследующие объектно-ориентированныевозможности:

  • множественноенаследование;
  • автоматическийвызов конструкторов (если вы хотите,чтобы при конструировании объектапроизводного класса вызывалсяконструктор базового класса, вампридется вызвать его явно);
  • абстрактныеклассы;
  • перегрузкаметодов;
  • перегрузкаоператоров (это связано с тем, что РНРявляется языком со свободной типизацией,- за дополнительной информациейобращайтесь к главе 2);
  • закрытый иоткрытый доступ, виртуальные функции;
  • деструкторы;
  • полиморфизм.

Но и безвсего перечисленного вы все равно сможетеизвлечь пользу из объектно-ориентированныхвозможностей, поддерживаемых РНР.Реализация ООП в РНР оказываетколоссальную помощь в модульном оформлениифункциональности вашей программы.

Классы,объекты и объявления методов

Классы образуютсинтаксическую базу объектно-ориентированногопрограммирования. Их можно рассматриватькак своего рода <контейнеры> для логическисвязанных данных и функций (обычноназываемых методами - см.ниже). Класс представляет собой шаблон, покоторому создаются конкретные экземпляры,используемые в программе. Экземплярыклассов называются объектами.

Чтобылучше понять связь между классами иобъектами, можно представить класс как <чертеж>для создания объектов. По чертежу <изготавливаются>разные объекты,обладающие одними и теми же базовымихарактеристиками (например, пристроительстве дома - одна дверь, два окна иопределенная толщина стены). Тем не менее,каждый объект существует независимо отдругих - изменение его характеристик никакне влияет на характеристики другихобъектов; например, в уже построенном домеможно прорубить дополнительное окно. Важнопомнить, что у объектов все равно остаетсяобщая характеристика - количество окон.

Класс такжеможно рассматривать как тип данных (см.главу 2), а объект - как переменную (поаналогии с тем, как переменная $counterотносится к целому, а переменная $last_name - кстроковому типу). Программа можетодновременно работать с несколькимиобъектами одного класса как с несколькимипеременными целого типа. Общий форматклассов РНР приведен в листинге 6.1.

Листинг6.1. Объявление классов в РНР

class Class_name { 

var$attribute_1;

...

var $attribute_N;

function function1() {

...

}

...

function functionN() {

...

} // end Class_name

Подведемитоги: объявление класса должно начинатьсяс ключевого слова class (подобно тому, какобъявление функции начинается с ключевогослова function). Каждому объявлению атрибута,содержащегося в классе, должнопредшествовать ключевое слово van. Атрибутымогут относиться к любому типу данных,поддерживаемых в РНР; их можнорассматривать как переменные с небольшимиразличиями, о которых вы узнаете в этойглаве. После объявлений атрибутов следуютобъявления методов, очень похожие натипичные объявления функций.

Пообщепринятым правилам имена классов ООПначинаются с прописной буквы, а все слова вименах методов, кроме первого, начинаются спрописных букв (первое слово начинается сострочной буквы). Разумеется, вы можетеиспользовать любые обозначения, которыесочтете удобными; главное - выберитестандарт и придерживайтесь его.

Методы частоиспользуются для работы с атрибутамиклассов. При ссылках на атрибуты внутриметодов используется специальнаяпеременная $this. Синтаксис методовпродемонстрирован в следующем примере:

<?

class Webpage {

van $bgcolor;

function setBgColor($color){

$this->bgcolor = $color;

}

function getBgColor() {

return $this->bgcolor;

}

}

?>

Переменная$this ссылается на экземпляр объекта, длякоторого вызывается метод. Поскольку влюбом классе может существовать несколькоэкземпляров объектов, уточнение $thisнеобходимо для ссылок на атрибуты,принадлежащие текущему объекту. Прииспользовании этого синтаксиса обратитевнимание на два обстоятельства:

атрибут,на который вы ссылаетесь в методе, ненужно передавать в видепараметра функции;

знакдоллара ($) ставится перед переменной $this, но неперед именем атрибута (каку обычной переменной).

Созданиеобъектов и работа с ними

Объектысоздаются оператором new. Например, объекткласса Webpage создается следующей командой:

$home_page = new Webpage;

Новый объектс именем $some_page обладает собственнымнабором атрибутов и методов, перечисленныхв классе Webpage. Для изменения значенияатрибута $bgcolor, принадлежащего этомуконкретному объекту, можно воспользоватьсяопределенным в классе методом setBgColor( ):

$some_page->setBgColor("black");

Следуетпомнить, что РНР также позволяет явнополучить значение атрибута указанием именобъекта и атрибута:

$some_page->bgcolor;

Однаковторой способ противоречит принципуинкапсуляции, и при работе с ООП поступатьтак не следует. Чтобы понять, почему это так,прочитайте следующий раздел.

Нарушениеинкапсуляции

Допустим, высоздали класс, один из атрибутов которогопредставляет собой массив. Но вместо тогочтобы работать с массивом черезпромежуточные методы (например,предназначенные для создания, удаления,модификации элементов и т. д.), вы в случаенеобходимости напрямую обращаетесь кмассиву. В течение месяца вы увереннопрограммируете большое <объектно-ориентированное>приложение и благосклонно принимаете хвалуколлег-программистов. Будущее сулит многорадостей - премии, оплачиваемый отпуск идаже отдельный кабинет.

Но вот черезмесяц после успешного запуска вашего web-приложенияваш начальник вдруг решает, что массивы вданном случае не годятся и работать синформацией нужно только через базу данных.

Какаянеприятность! Поскольку вы решили работатьс атрибутами напрямую, вам теперь придетсяпросматривать всю программу и везде, гдепроисходят обращения к данным, вноситьисправления в соответствии с новыминтерфейсом. Задача весьма хлопотная, ктому же чревата риском внесения новыхошибок.

А теперьдавайте посмотрим, что произошло бы приработе с данными с использованием методов.Все, что вам пришлось бы сделать припереходе от массива к базе данных -перепрограммировать методы. Модификацияавтоматически распространяется на всеточки программы, в которых присутствуютвызовы методов.

Конструкторы

Довольночасто при создании объекта требуетсязадать значения некоторых атрибутов. Ксчастью, разработчики технологии ООП учлиэто обстоятельство и реализовали его вконцепции конструкторов. Конструкторпредставляет собой метод, который задаетзначения некоторых атрибутов (а также можетвызывать другие методы). Конструкторывызываются автоматически при созданииновых объектов. Чтобы это стало возможным,имя метода-конструктора должно совпадать сименем класса, в котором он содержится.Пример конструктора приведен в листинге 6.2.

Листинг6.2. Использованиеконструктора

<?

class Webpage { 

var$bgcolor;

function Webpage($color){

$this->bgcolor = $color;

}

}

// Вызватьконструктор класса Webpage

$page = new Webpage("brown");

?>

Раньшесоздание объекта и инициализация атрибутоввыполнялись раздельно. Конструкторыпозволяют выполнить эти действия за одинэтап.

Интереснаяподробность: в зависимости от количествапередаваемых параметров могут вызыватьсяразные конструкторы. Например, в листинге 6.2объекты класса Webpage могут создаваться двумяспособами. Во-первых, вы можете вызватьконструктор, который просто создает объект,но не инициализирует его атрибуты:

$page = new Webpage;

Во-вторых,объект можно создать при помощиконструктора, определенного в классе, - вэтом случае вы создаете объект класса Webpage иприсваиваете значение его атрибуту bgcolor:

$page = new Webpage("brown");

Деструкторы

Какупоминалось ранее, в РНР отсутствуетнепосредственная поддержка деструкторов.Тем не менее, вы можете легко имитироватьработу деструктора, вызывая функцию РНР unset(). Эта функция уничтожает содержимоепеременной и возвращает занимаемые еюресурсы системе. С объектами unset( ) работаеттак же, как и с переменными. Допустим, выработаете с объектом $Webpage. После завершенияработы с этим конкретным объектомвызывается функция

unset($Webpage);

Эта командаудаляет из памяти все содержимое $Webpage.Действуя в духе инкапсуляции, можнопоместить вызов unset( ) в метод с именем destroy( ) изатем вызвать его:

$Website->destroy( );

Помните:необходимость в вызове деструктороввозникает лишь при работе с объектами,использующими большой объем ресурсов,поскольку все переменные и объектыавтоматически уничтожаются по завершениисценария.

Простое ииерархическое наследование

Какговорилось выше, класс является шаблоном,по которому создаются реальные объекты сопределенными характеристиками ифункциями. Нетрудно представить себеситуацию, при которой такой объект являетсячастью другого объекта. Например,автомобиль можно считать частным случаемкатегории <транспортное средство>, ккоторой относятся и самолеты. Хотя разныетипы транспортных средств сильноотличаются друг от друга, все онихарактеризуются атрибутами из общегонабора (количество колес, мощность,максимальная скорость, модель и т. д.). Пустьконкретные значения этих атрибутов сильноразличаются - атрибуты все равно присущивсем транспортным средствам. Таким образом,субклассы <автомобиль>и <самолет> наследуют общий набор базовыххарактеристик от суперкласса<транспортное средство>.Концепция получения классом характеристикот другого, более общего класса называется наследованием.

Наследованиеявляется исключительно полезным средствомпрограммирования, поскольку его применениепредотвращает копирование кода, совместноиспользуемого структурами данных, -например, общих характеристик различныхтипов транспортных средств, упоминавшихсяв предыдущем абзаце. В общем случаесинтаксис наследования характеристикдругого класса в РНР выглядит так:

class Class_name2extends Class_name1 {

объявленияатрибутов;

объявленияметодов;

}

Ключевоеслово extends говорит о том, что класс Class_name2наследует все характеристики класса Class_name1.

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

модификациипрограммы. Например, в иерархии,изображенной на рис. 6.1, изменения в классе <автомобиль>никак не отразятся на коде (и данных) класса<самолет>, и наоборот.

Вызовконструктора производного класса неприводит к автоматическому вызову конструкторабазового класса.

Рис. 6.1. Иерархиятранспортных средств

В листинге 6.3приведены классы, моделирующие иерархию,изображенную на рис. 6.1.

Листинг6.3. Представлениеразличных типов транспортных средств припомощи наследования

<?

//Транспортное средство 

class Vehicle {

var $model;

var $current_speed;

function setSpeed($mph){

$this->current_speed= $mph;

}

function getSpeed() {

return $this->current_speed;

}

}

// Автомобиль

class Auto extendsVehicle { 

var $fue1_type;

function setFuelType($fuel){

$this->fuel_type = $fuel;

}

function getFuelType(){

return $this->fuel_type;

}

}

// Самолет

class Airplane extendsVehicle {

var $wingspan;

function setWingSpan($wingspan){

$this->wingspan = $wingspan;

}

function getWingSpan(){

return $this->wingspan;

}

}

?>

Объекты этихклассов создаются следующим образом:

$tractor = new Vehicle;

$gulfstream = new Airplane;

Приведенныекоманды создают два объекта. Первый объект,$tractor, относится к классу Vehicle. Второй объект,$gulfstream, относится к классу Airplane и потомуобладает как общими характеристикамикласса Vehicle, так и уточненнымихарактеристиками класса Airplаne.

Ситуация,при которой класс наследует свойстванескольких родительских классов,называется множественным наследованием. Ксожалению, в РНР множественноенаследование не поддерживается. Например,следующая конструкция невозможна в РНР:

class Airplane extendsVehicle extends Building...

Многоуровневоенаследование

Сувеличением размеров и сложности программможет возникнуть необходимость вмногоуровневом наследовании. Иначе говоря,класс будет наследовать свои свойства отдругих классов, которые, в свою очередь,будут наследовать от третьих классов и т. д.Многоуровневое наследование развиваетмодульную структуру программы, обеспечиваяпростоту сопровождения и более четкуюлогическую структуру. Скажем, прииспользовании примера с транспортнымисредствами в большой программе можетпоявиться необходимость в дополнительномразбиении на субклассы суперкласса Vehicle,продолжающем логическое развитие иерархии.Например, транспортные средства можнодополнительно разделить на наземные,морские и воздушные, чтобы суперклассспециализированных субклассов выбирался взависимости от среды, в которойперемещается данное транспортное средство.Новый вариант иерархии показан на рис. 6.2.

Краткийпример, приведенный в листинге 6.4,подчеркивает некоторые важные аспектымногоуровневого наследования в РНР.

Листинг6.4. Многоуровневоенаследование

<?

class Vehicle {

Объявленияатрибутов...

Объявленияметодов...

}

class Land extendsVehicle {

  Объявления атрибутов...

  Объявленияметодов...

}

class Саr extendsLand {

  Объявления атрибутов...

  Объявленияметодов...

}

$nissan = new Car;

?>

Объект $nissanсодержит все атрибуты и методы классов Саr,Land и Vehicle. Как видите, программа получаетсяисключительно модульной. Допустим, когда-тов будущем вы захотите добавить в класс Landновый атрибут. Нет проблем: внеситесоответствующие изменения в класс Land, иэтот атрибут немедленно становитсядоступным для классов Land и Саr, не влияя нафункциональность других классов. Такимобразом, модульность кода и гибкостьотносятся к числу основных преимуществ ООП.

 

Рис. 6.2. Многоуровневоенаследование в иерархии Vehicle

Хотямасс наследует свои характеристики отцепочки родителей, конструкторы родительскихклассов не вызываются автоматически присоздании объектов класса-наследника. Этиконструкторы могут вызываться классом-наследникомв виде методов.

Абстрактныеклассы

Внекоторых ситуациях бывает удобно создатькласс, объекты которого никогда несоздаются (данный класс нужен всего лишькак базовый для создания производныхклассов). Такие классы называются абстрактными.Абстрактные классыобычноприменяются в тех случаях, когдаразработчик программы хочет обеспечитьобязательную поддержку некоторыхфункциональных возможностей всемиклассами, производными от абстрактногобазового класса.

В РНРотсутствует прямая поддержка абстрактныхклассов, однако существует простоеобходное решение - достаточно определить в<абстрактном> классе конструктор ивключить в него вызов die( ). Вернемся кклассам из листинга 6.4. Скорее всего, вамникогда не придется создавать экземплярыклассов Land и Vehicle, поскольку они не могутпредставлять физические объекты. Дляпредставления реальных объектов (например,автомобилей) следует создать класс,производный от этих классов. Следовательно,чтобы предотвратить возможное созданиеобъектов классов Land и Vehicle, необходимовключить в их конструкторы вызовы die( ), какпоказано в листинге 6.5.

Листинг6.5. Созданиеабстрактных классов

<?

class Vehicle {

Объявленияатрибутов...

function Vehicle() }

die ("Cannotcreate Abstract Vehicle class!");

}

Объявлениядругих методов...

}

class Land extendsVehicle {

Объявленияатрибутов...

function Land() }

die ("Cannotcreate Abstract Land class!");

}

Объявлениядругих методов. } class Car extends Land {

Объявленияатрибутов...

Объявленияметодов...

}

?>

Попыткасоздания экземпляра этих абстрактныхклассов приведет к выдаче сообщения обошибке и завершению программы.

Перегрузкаметодов

Перегрузкойметодов называетсяопределение нескольких методов содинаковыми именами, но разным количествомили типом параметров. Как и в случае сабстрактными классами, в РНР этавозможность не поддерживается, носуществует простое обходное решение,приведенное в листинге 6.6.

Листинг6.6. Перегрузкаметодов

<?

class Page {

var $bgcolor;

var $textcolor;

 function Page() {

// Определитьколичество переданных аргументов

// и вызватьметод с нужным именем

$name = "Page".func_num_args();

// Call $name withcorrect number of arguments passed in

if ( func_num_args() ==0 ) :

$this->$name();

else:

$this->$name(func_get_arg(0));

endif;

}

function Page0() {

$this->bgcolor ="white";

$this->textcolor = "black";

print "Createddefault page";

}

function Page1($bgcolor){

$this->bgcolor =$bgcolor;

$this->textcolor = "black";

print "Created custompage";

}

}

$html_page - new Page("red");

?>

В этомпримере при создании нового объекта сименем $html_page передается один аргумент.Поскольку в классе был определенконструктор по умолчанию (Раgе( )),вызывается именно он. Однако конструктор поумолчанию всего лишь выбирает, какому изконструкторов (Page0( ) или Page1( )) следуетпередать управление. При выбореконструктора используются функции func_num_args()и func_get_arg( ), которые, соответственно,определяют количество аргументов и читаютэти аргументы.

Конечно,такое решение вряд ли можно назватьполноценной перегрузкой, но оно подойдетдля тех, кто не может жить без этого важногоаспекта ООП.

Функции дляработы с классами и объектами

В РНРсуществует несколько стандартных функцийдля работы с классами и объектами; этифункции рассматриваются в следующихразделах. Все они часто используются напрактике, особенно в процессе разработкиинтерфейса, администрирования кода идиагностики ошибок.

get_class_methods( )

Функцияget_class_methods( ) возвращает массив имен методовкласса с заданным именем. Синтаксис функцииget_class_methods( ):

array get_class_methods(string имя_класса)

Простойпример использования get_class_methods( ) приведен влистинге 6.7.

Листинг6.7. Получениесписка методов класса

<?

...

class Airplane extendsVehicle { 

var $wingspan;

function setWingSpan($wingspan){ 

$this->wingspan = $wingspan;

}

function getWingSpan(){ 

return $this->wingspan;

}

}

$cls_methods =get_class_methods(Airplane);

// Массив$cls_methods содержит имена всех методов,

//объявленных в классах "Airplane" и "Vehicle"

?>

Как видно излистинга 6.7, функция get_class_methods( ) позволяетлегко получить информацию обо всех методах,поддерживаемых классом.

get_class_vars( )

Функцияget_class_vars( ) возвращает массив имен атрибутовкласса с заданным именем. Синтаксис функцииget_class_vars( ):

array get_class_vars(string имя_класса)

Примериспользования get_class_vars( ) приведен в листинге6.8.

Листинг6.8. Получениесписка атрибутов класса функцией get_class_vars( )

<?

class Vehicle {

var $model;

var $current_speed; }

class Airplane extendsVehicle {

var Swingspan; }$a_class = "Airplane";

$attribs = get_class_vars($a_class);

// $attribs = array ("wingspan", "model", "current_speed")

?>

Массив $attribsзаполняется именами всех атрибутов классаAirplane.

get_object_vars( )

Функцияget_object_vars( ) возвращает ассоциативный массивс информацией обо всех атрибутах объекта сзаданным именем. Синтаксис функции get_object_vars():

array get_object_vars (objectимя_обьекта)

Примериспользования функции get_object_vars( ) приведен влистинге 6.9.

Листинг6.9. Получениеинформации о переменных объекта 

<?

class Vehicle {

var Swheels;

}

class Land extendsVehicle {

var Sengine;

}

class car extends Land{

var $doors:

function car($doors,$eng, $wheels) {

$this->doors = $doors;

$this->engine = $eng;

$this->wheels= $wheels;

}

function get_wheels() {

return $this->wheels;

}

}

$toyota = new car(2,400,4);

$vars = get_object_vars($toyota);

while (list($key, $value) =each($vars)) :

print "$key ==> $value <br>";

endwhile;

// Выходныеданные:

// doors ==> 2

// engine ==> 400

// wheels ==> 2

?>

Функцияget_object_vars( ) позволяет быстро получить всюинформацию об атрибутах конкретногообъекта и их значениях в видеассоциативного массива.

method_exists( )

Функцияmethod_exists( ) проверяет, поддерживается лиобъектом метод с заданным именем. Еслиметод поддерживается, функция возвращаетTRUE, в противном случае возвращается FALSE.Синтаксис функции method_exists( ):

bool method_exi sts (object имя_обьекта.string имя_метода)

Примериспользования метода method_exists( ) приведён влистинге 6.10.

Листинг6.10. Проверкаподдержки метода объектом при помощифункции method_exists()

<?

class Vehicle {

...

}

class Land extendsVehicle {

var $fourWheel;

function setFourWheel Drive() {

$this->fourWeel = 1;

}

}

// Создатьобъект с именем $саr

$car = new Land;

// Если метод"fourWheelDrive" поддерживается классом "Land"

// или "Vehicle", вызов method_exists возвращаетTRUE;

// в противном случае возвращаетсяFALSE.

//В данном примере method_exists() возвращает TRUE.

if (method_exists($car,"setfourWheelDrive")) :

print "This car isequipped with 4-wheel drive";

else :

print "This car isnot equipped with 4-wheel drive";

endif;

?>

В листинге6.10 функция method_exists ( ) проверяет,поддерживается ли объектом $car метод сименем setFourWheelDrive( ). Если методподдерживается, функция возвращаетлогическую истину и фрагмент выводитсоответствующее сообщение. В противномслучае возвращается FALSE и выводится другоесообщение.

get_class( )

Функцияget_class( ) возвращает имя класса, к которомуотносится объект с заданным именем.Синтаксис функции get_class( ):

string get_class(object имя_объекта);

Примериспользования get_class( ) приведен в листинге6.11.

Листинг6.11.Получениеимени класса функцией get_class( )

<?

class Vehicle {

...

class Land extendsVehicle {

...

}

// Создатьобъект с именем $саr $car = new Land;

// Переменной$class_a присваивается строка "Land"

$class_a = get_class($car);

?>

В результатепеременной $class_a присваивается имя класса,на основе которого был создан объект $саr.

get_parent_class( )

Функцияget_parent_class( ) возвращает имя родительскогокласса (если он есть) для объекта с заданнымименем. Синтаксис функции get_parent_dass( ):

string get_parent_class(object имя_обьекта);

Листинг6.12 демонстрирует использование get_parent_class( ).

Листинг6.12. Получениеимени родительского класса функциейget_parent_class( )

<?

class Vehicle {

...

}

class Land extendsVehicle {

...

}

// Создатьобъект с именем$саr $саr = new Land;

// Переменной$parent присваивается строка "Vehicle"

$parent = get_parent_dass($car);

?>

Как иследовало ожидать, при вызове get_parent_class( )переменной $parent будет присвоена строка "Vehicle".

is_subclass_of( )

Функцияis_subclass_of( ) проверяет, был ли объект создан набазе класса, имеющего родительский класс сзаданным именем. Функция возвращает TRUE,если проверка дает положительный результат,и FALSE в противном случае. Синтаксис функцииis_subclass_of( ):

bool is_subclass_of (object объект,string имя_класса)

Использованиеis_subclass_of( ) продемонстрировано в листинге 6.13.

Листинг6.13.Использованиефункции is_subdass_of( )

<?

class Vehicle {

...

}

class Land extendsVehicle {

...

}

$auto = new Land;

// Переменной$is_subclass присваивается TRUE

$is_subclass =is_subclass_of($auto, "Vehicle");

?>

В листинге6.13 переменной $is_subclass( ) присваиваетсяпризнак того, принадлежит ли объект $auto ксубклассу родительского класса Vehicle. Вприведенном фрагменте $auto относится кклассу Vehicle; следовательно, переменной $is_subclass() будет присвоено значение TRUE.

get_declared_classes( )

Функцияget_declared_classes( ) возвращает массив с именамивсех определенных классов (листинг 6.14).Синтаксис функции get_declared_classes( ):

array get_declared_classes()

Листинг6.14. Получениесписка классов функцией get_declared_classes( )

<?

class Vehicle {

...

}

class Land extendsVehicle {

...

}

$declared_classes =get_declared_classes();

// $declared_classes = array("Vehicle", "Land")

?>

Итоги

В этой главебыли представлены некоторые концепцииобъектно-ориентированногопрограммирования, при этом особое вниманиеуделялось их реализации в языке РНР. Вчастности, были рассмотрены следующие темы:

  • общиепринципы объектно-ориентированногопрограммирования;
  • классы,объекты и методы;
  • простое ииерархическое наследование;
  • абстрактныеклассы;
  • перегрузкаметодов;
  • функциидля работы с классами и объектами в РНР.

Технологияобъектно-ориентированногопрограммирования не очень сложна, но полноеусвоение всех концепций обычно требуетнекоторого времени. Однако я гарантирую,что затраченное время полностью окупится -ООП поднимет эффективность вашей работы напринципиально новый уровень.