Наследование личных атрибутов в 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) во внешний мир, так как:

  1. Что касается этого класса, то подкласс является частью внешнего мира.
  2. Учитывая общий совет - "предпочесть композицию, а не наследование", кажется странным отдавать предпочтение наследованию или предоставлять механизм, который мешает рефакторингу от наследования к композиции.

Атрибуты в 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;

Работает по желанию.

Другие вопросы по тегам