2014-02-19 2 views
1

Я новичок в наследовании Perl и не смог найти явные инструкции для наследования родительского конструктора. Я предположил, что все методы (включая конструктор) из родительского класса наследуются, но, похоже, это не так. Таким образом, это не достаточно:Inherit Parent Constructor

package Child; 
use strict; 
use Parent; 
our @ISA=qw(Parent); 

Вместо этого мне нужно добавить конструктор, который вызывает родительский конструктор:

package Child; 
use strict; 
use Parent; 
our @ISA=qw(Parent); 

sub new { 
    my $self=Parent::new(shift); 
    bless $self; 
    return $self; 
} 

Возможно, кто-то может прояснить логику для меня и скажите мне, если родительский конструктор наследоваться, не выполняя то, что я сделал выше (явное объявление и вызов родительского конструктора)?

+0

Не является «новым» только другим методом и используется как конструктор только в качестве условного обозначения? –

+1

Если вы используете файловую систему без учета регистра, у вас возникнет конфликт между вашей «родительской» и «родительской» прагмой. – ysth

+0

'base.pm' все еще существует и по-прежнему распространяется с Perl, но это не особенно рекомендуется. В него встроено множество трещин, которые касаются прагмы «полей», которую никто не использует. – tobyink

ответ

6

Вам не нужно это делать; что-то не так где-то в вашем коде.

Это полный рабочий пример:

main.pl:

use strict; 
use warnings; 
use Subclass; 
my $object = Subclass->new(); 
print "object is a ", ref $object, "\n"; 

Subclass.pm:

package Subclass; 
use strict; 
use warnings; 
use parent 'Superclass'; 
1; 

Superclass.pm:

package Superclass; 
use strict; 
use warnings; 
sub new { 
    my $class = $_[0]; 
    return bless {}, $class; 
} 
1; 

use parent 'Superclass' только грузы Суперкласс и набор @ISA для вас.

-1

Часто, если вы хотите, чтобы конструктор одного класса вызывал родительский класс, это будет обрабатываться «psuedo-class» SUPER.

package Derived; 
use parent 'Base'; 

sub new { 
    my $class_name = shift; 
    my $self  = $class_name->SUPER::new(@_); 

    return init_Derived($self); 
} 

Это будет работать только с одним спуском. С несколькими родителями вы должны собрать их вместе.

0

В соответствии с ответом @ ysth вам не нужно переопределять родительский конструктор, если вам не нужно делать что-то особенное в своем конструкторе. В этом случае, как вы обычно делаете это будет выглядеть так:

sub new { 
    my $class = shift; 
    my $self = $class->SUPER::new(@_); 
    ...; 
    return $self; 
} 

В догадке, причина наследования не работает должным образом, что вы могли бы использовать в один аргумент формы bless в суперкласса , Что-то вроде этого:

bless $self; 

За исключением очень необычных обстоятельствах, вы всегда должны отдавать предпочтение версии два аргументами bless:

bless $self, $class; 

Где $class это первый аргумент, переданный new подразделам.

Смежные вопросы