На этом шаге мы рассмотрим методы класса и методы объекта.
Различают методы класса и методы объекта, которые называют также статическими и виртуальными, соответственно. Первым аргументом метода должна быть ссылка, представляющая объект, или имя пакета. То, каким образом каждый метод обрабатывает свой первый аргумент, определяет, является ли он методом класса или методом объекта.
Статические методы применяются к целому классу, а не к отдельным его объектам. В качестве первого аргумента статическому методу передается имя класса. Типичным примером статических методов являются конструкторы. В Perl методы выполняются в пространстве имен того пакета, в котором они были определены, а не в пространстве имен пакета, в котором они вызваны. Поэтому статические методы часто свой первый аргумент игнорируют, так как и без него известно, к какому пакету метод принадлежит. Последнее не относится к конструкторам, передающим свой первый аргумент функции bless() в качестве имени класса.
Методы объекта применяются к отдельному объекту. Их первым аргументом должна быть ссылка, указывающая на объект, к которому применяется данный метод. Методы объекта могут выполнять разные действия, но наиболее типичными являются действия, связанные с отображением и изменением данных, инкапсулированных в объекте. В примере из предыдущего шага мы присвоили значения, а затем их распечатали, обращаясь к данным объекта напрямую. Таким способом мы просто продемонстрировали, что конструктор действительно возвращает ссылку, представляющую объект. В действительности это плохой способ, и применять его не рекомендуется. В некоторых объектно-ориентированных языках программирования прямой доступ к данным объекта вообще невозможен. Объект следует рассматривать как "черный ящик", содержимое которого можно получить или изменить, только используя методы объекта. Такое ограничение помогает сохранить целостность и скрыть некоторые внутренние данные объекта. Отредактируем текст примера из предыдущего шага, дополнив его методами, которые используются для изменения и просмотра данных.
#! perl -w #Модуль класса Staff.pm: package Staff; require Exporter; @ISA = qw (Exporter); @EXPORT = qw (new showdata setdata); sub new { my ($class, @items) = shift; my $self = {}; bless $self, $class; return $self; } sub showdata { my $self = shift; my @keys = @_ ? @_ : sort keys %$self; foreach $key (@keys) { print "\t$key => $self->{$key}\n"; } return $self; } sub setdata { my ($self, $data) = @_; for $i (keys %$data) { $self->{$i}=$data->{$i}; } return $self; }
В данном примере по сравнению с предыдущим изменен конструктор new(). Теперь второй параметр, представленный локальной переменной $data, содержит ссылку. Эту ссылку функция bless() свяжет с классом staff, превратив в его объект. Таким образом, при помощи этого параметра можно управлять типом внутренней структуры данных, которая и представляет объект. Это может быть ссылка на хеш-массив, массив, скаляр и т. д. Параметры, передаваемые конструктору, называют переменными объекта. Они используются для того, чтобы установить начальные значения данных каждого вновь создаваемого объекта.
Если обратиться к основной программе:
#! perl -w
use Staff;
$someone=new(Staff, {"имя"=>"","фамилия"=>""});
setdata ($someone, {
"имя"=>"Максим",
"фамилия"=>"Исаев",
"возраст"=>42,
"занятия спортом"=>"теннис"});
showdata($someone);
Рис.1. Результаты работы скрипта
На следующем шаге мы рассмотрим вызов метода.