Родительский метод, использующий переменную, определенную в дочернем классе - PullRequest
1 голос
/ 03 мая 2019

В Python вы можете сделать:

class Binance(Exchange):
    name = "Binance"
    code = "binance"

и в родительском классе есть

class Exchange:
    @classmethod
    def get_name(cls):
    return cls.name

Теперь Perl!

Это прекрасно.Я хочу то же самое для моих объектов Perl.

package DWDESReader;
use base qw(DWConfigFileReader);
our $type = "DES";

и в базовом классе:

package DWConfigFileReader;

our $type = "";

sub new {
    my ($class, %args) = @_;
    $args{type} = $type;

    return bless {%args}, $class;
}

sub getType {
    my ($self) = @_;
    return $self->{type};
}

Но это не работает, то есть возвращает только пустую строку, назначенную в базеучебный класс.Я не ожидал, что это сработает, но не уверен, как это должно быть сделано.

Ответы [ 3 ]

4 голосов
/ 04 мая 2019

Классы не имеют атрибутов (переменных) в Perl, только методы (sub).

Я рекомендую создать метод абстрактного виртуального класса.

package DWConfigFileReader;

use Carp qw( croak );

sub new {
    my ($class, %args) = @_;
    my $self = bless(\%args, $class);
    return $self;
}

sub type { croak("Subclass must override \"type\"."); }

1;

package DWDESReader;

use parent 'DWConfigFileReader';

sub type { "DES" }

1;

Тебе даже не нужно $self->{type} = $class->type;;просто используйте $self->type вместо $self->{type}.

4 голосов
/ 03 мая 2019

Не понимаю, зачем это нужно, но это возможно, если выключить строгий refs:

#!/usr/bin/perl
use warnings;
use strict;

{   package My::Base;

    sub new { bless {}, shift }
    our $name = 'Base';
    sub get_name {
        my ($self) = @_;
        my $class = ref $self || $self;
        do { no strict 'refs';
             ${ $class . '::name' }
         }
    }
}

{   package My::Child;
    use parent -norequire => 'My::Base';
    our $name = 'Child';
}

my $ch = 'My::Child'->new;
print $ch->get_name, ' ', 'My::Child'->get_name;

Но обычно вы просто определяете метод класса, содержащий имя:

{   package My::Base;

    sub new { bless {}, shift }
    sub name { 'Base' }
    sub get_name { shift->name }
}

{   package My::Child;
    use parent -norequire => 'My::Base';
    sub name { 'Child' }
}
3 голосов
/ 03 мая 2019

Как уже было предложено, Perl наследует методы (sub), а не переменные, но константы на самом деле являются sub, поэтому вы можете сделать что-то похожее на это.

package DWDESReader;
use base qw(DWConfigFileReader);
use constant TYPE => "DES";

Затем, если вы вызовете $self->TYPEгде-то в базовом классе вы получите «DES», если объект на самом деле является объектом DWDESReader.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...