Для того чтобы надежно обеспечить ограничение доступа к данным, которые хранятся в объекте, применяются замыкания. Чтобы показать, как можно организовать полностью закрытые атрибуты (private attributes) с помощью замыканий, напишем класс
package Private::Person; # класс "Личность"
sub new { # прототипом может быть
my $invocant = shift; # класс или объект
my $class = ref($invocant) || $invocant;
my $self = { # значения атрибутов:
NAME => '', # имя и
HEIGHT => 0.0 # рост
};
my $closure = sub { # функция доступа к данным
my $field = shift; # по имени атрибута
$self->{$field} = shift if @_; # изменим и
return $self->{$field}; # вернем значение
}; # объектом будет
bless($closure, $class); # ссылка на функцию
}
# метод доступа к атрибуту name
sub name {
my $self = shift; # ссылка на объект-функцию
&{$self}("NAME", @_); # доступ к скрытому значению
}
# метод доступа к атрибуту height
sub height { # то же, что выше, но несколько короче:
&{ $_[0] }("HEIGHT", @_[1 .. $#_ ] )
}
1;
Методы доступа к свойствам объектов получают первым аргументом ссылку на функцию доступа к значениям атрибутов и вызывают ее, передавая ей имя поля и остальные свои аргументы. Приведем пример создания объектов нового класса и обращения к их методам. В вызывающей программе все выглядит так, как будто данные по-прежнему хранятся в анонимном массиве:
package main; # вызывающая программа
use Private::Person; # использовать этот класс
my $elf = Private::Person->new; # создать объект и
$elf->name("Леголас"); # задать значения
$elf->height(189); # его атрибутам
# получить доступ к значениям атрибутов объекта
print $elf->name, ' ', $elf->height, ' ';
print ref($elf), "\n"; # тип референта: 'Private::Person'
Из примера видно, что имя класса может быть составным, отражая иерархию классов. Поскольку классы - это пакеты, хранящиеся в файле-модуле, то все, что говорилось в предыдущей лекции об именовании модулей, относится и к классам.
Обратите также внимание на то, что конструктор класса
my $class = ref($invocant) || $invocant;
Если первым аргументом передана ссылка на объект, то определяется имя его класса, иначе считается, что передано имя класса. Поэтому в программе можно создавать однотипные объекты, обращаясь к методу
my $hobbit = Private::Person->new; # вызов с именем класса
$hobbit->name("Bilbo Baggins");
my $frodo = $hobbit->new; # вызов со ссылкой на объект
$frodo->name("Frodo Baggins");
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии