Наследование личных атрибутов в Perl 6
Я ничего не могу найти в документации, но кажется, что в подклассе нет доступа к закрытым переменным его суперкласса. Я прав?
class A {
has $!a;
}
class B is A {
has $.b;
method set_a($x) {
$!a = $x;
}
}
my $var = B.new();
$var.set_a(5);
say $var.a;
Это дает сообщение об ошибке:
Attribute $!a not declared in class B
Кстати, где читать о классах в документах? Я только нашел довольно короткий раздел Классы и объекты.
1 ответ
В Perl 6 атрибут, объявленный в классе, доступен только внутри этого класса. Это означает, что можно уверенно проводить рефакторинг состояния в классе, не беспокоясь ни о каком использовании этого состояния за пределами класса.
Подклассы не получают никакого специального доступа в отношении атрибутов. Некоторые языки обеспечивают protected
модификатор. Это не существует в Perl 6, по замыслу. Либо что-то личное для этого класса, либо has $.a
) во внешний мир, так как:
- Что касается этого класса, то подкласс является частью внешнего мира.
- Учитывая общий совет - "предпочесть композицию, а не наследование", кажется странным отдавать предпочтение наследованию или предоставлять механизм, который мешает рефакторингу от наследования к композиции.
Атрибуты в role
напротив, они объединены в класс и работают так, как если бы они были объявлены в самом классе. Следовательно, атрибут из role
может использоваться в теле класса. Если вы хотите написать повторно используемые части функциональности в контексте ОО, более типично использовать роли и состав в Perl 6, а не наследование. Действительно, написание исходного кода как:
role A {
has $!a;
}
class B does A {
has $.b;
method set_a($x) {
$!a = $x;
}
method a() { $!a }
}
my $var = B.new();
$var.set_a(5);
say $var.a;
Работает по желанию.