我正在尝试学习Perl中的继承。
这是我的目录结构:
perldir
perldir \ child.pl
perldir \ MYLIB
perldir \ MYLIB \ Parent.pm
Parent.pm
package Parent;
sub new {
my $class = shift;
my $self = { _first => shift, _last => shift };
bless $self, $class;
}
sub getFirstName {
my ($self) = @_;
return $self->{ _first };
}
1;
child.pl
package Child;
use parent 'Mylib::Parent';
sub new {
my $class = shift;
my $self = Parent->new( shift, shift );
bless $self, $class;
}
my $obj = new Child('Jack', 'Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName(); #Error
最后一行抛出的错误是:无法通过child.pl第13行的包“AChild”找到对象方法“getFirstName”;
如果我执行以下操作之一,该程序将起作用:
1.我在Mylib目录下有两个文件
2.我替换
use parent 'Mylib::Parent'
与
use Mylib::Parent;
@ISA = ('Parent');
是否可以使用'use parent'和子类在不同的目录中使程序工作?
==========================
根据choroba的答案更新了问题。
好的,我更改了类以反映以下内容:
Parent.pm
package Mylib::Parent;
sub new {
my $class = shift;
my $self = { _first => shift, _last => shift };
bless $self, $class;
}
sub getFirstName {
my ($self) = @_;
return $self->{ _first };
}
1;
child.pl
package Child;
use parent 'Mylib::Parent';
sub new {
my $class = shift;
my $self = Mylib::Parent->new( shift, shift );
bless $self, $class;
}
my $obj = new Child('Jack', 'Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName();
以上工作正常。现在考虑我希望另一个子类与Parent.pm。
位于同一目录中perldir \ MYLIB \ ChildTwo.pl
package ChildTwo; #or package Mylib::ChildTwo;
use parent 'Mylib::Parent'; #or use parent 'Parent';
sub new {
my $class = shift;
my $self = Mylib::Parent->new( shift, shift ); #or Parent->new(shift, shift);
bless $self, $class;
}
my $obj = new ChildTwo('Jack', 'Sparrow'); #or new Mylib::ChildTwo('Jack','Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName();
1;
以上不起作用。我可以让ChildTwo.pl与Child.pl一起使用而不使用'use lib'吗?
答案 0 :(得分:3)
您必须下定决心:父包名称为Parent
,然后是child.pl
:
use parent 'Parent';
告诉perl在哪里搜索它:
perl -IMylib child.pl
或使用lib
use FindBin;
use lib "$FindBin::Bin/Mylib";
或者,包的名称是Mylib::Parent
,那么你必须修改包声明:
package Mylib::Parent;
并调用正确的构造函数:
my $self = Mylib::Parent->new( shift, shift );
答案 1 :(得分:0)
我的目标是了解类在驻留在各种包中时如何相互使用。看来,与Java不同的是,' lib'通常表示第三方jar,Perl中的lib表示包含特定于脚本的所有包的根。
似乎'使用lib(dirpath)' 必须使用。 查看用法 ChildThree.pm 强>
目录结构:
/perldir/child.pl
/perldir/use_child_two.pl
/perldir/use_child_three.pl
/perldir/Mylib/Parent.pm
/perldir/Mylib/ChildTwo.pm
/perldir/Secondlib/ChildThree.pm
<强> /perldir/Mylib/Parent.pm 强>
package Mylib::Parent;
sub new {
my $class = shift;
my $self = { _first => shift, _last => shift };
bless $self, $class;
}
sub getFirstName {
my ($self) = @_;
return $self->{ _first };
}
1;
<强> /perldir/child.pl 强>
package Child;
use parent 'Mylib::Parent';
sub new {
my $class = shift;
my $self = Mylib::Parent->new( shift, shift );
bless $self, $class;
}
my $obj = new Child('Jack', 'Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName();
<强> /perldir/Mylib/ChildTwo.pm 强>
package Mylib::ChildTwo;
use parent 'Mylib::Parent';
sub new {
my $class = shift;
my $self = Mylib::Parent->new( shift, shift );
bless $self, $class;
}
1;
<强> /perldir/use_child_two.pl 强>
use Scalar::Util ('blessed');
use Mylib::ChildTwo;
my $obj = new Mylib::ChildTwo('Jack', 'Sparrow');
print "\n Class: ", blessed ( $obj );
print "\n ",$obj->{_first},' ',$obj->{_last};
print "\n ",$obj->getFirstName();
1;
<强> /perldir/Secondlib/ChildThree.pm 强>
package Secondlib::ChildThree;
use lib '/perldir'; #Adds directories to search path to discover
#package structure and finding module 'Mylib::Parent'
use parent 'Mylib::Parent';
sub new {
my $class = shift;
my $self = Mylib::Parent->new( shift, shift );
bless $self, $class;
}
1;
<强> /perldir/use_child_three.pl 强>
use Scalar::Util ('blessed');
use Secondlib::ChildThree;
my $obj = new Secondlib::ChildThree('Jack', 'Sparrow');
print "\n Class: ", blessed ( $obj );
print "\n ",$obj->{_first},' ',$obj->{_last};
print "\n ",$obj->getFirstName();
1;
答案 2 :(得分:0)
默认情况下,不应在普通的Perl脚本中使用package
。 package
声明用于创建新的名称空间,以防止模块之间发生命名冲突。
为简单起见,您不必创建用于定义包的模块目录。事实上,在面向对象的Perl中,如果不打算在其他程序之间共享,那么在主程序中定义类的情况并不少见。
这是一个简单的继承示例。我创建了两个对象。 $wife
是一个类Person
,而$me
是一个名为Developer
的Person的子类。请注意,我没有new
或name
子例程 ..我的意思是.. 方法 在我的定义中Developer
课程。那些由我的use parent -norequire qw(Person);
声明继承。
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use Data::Dumper;
my $wife = Person->new();
$wife->name("Susan");
$wife->occupation("Quantum Physicist");
say "Name: " . $wife->name;
say "Occupation: " . $wife->occupation . "\n";
my $me = Developer->new("Bob");
$me->programming_language("Perl");
say "Name: " . $me->name;
say "Language: " . $me->programming_language;
########################################################################
########################################################################
package Person;
sub new {
my $class = shift;
my $name = shift;
my $occupation = shift;
my $self = {};
bless $self, $class;
$self->name($name);
$self->occupation($occupation);
return $self;
}
sub name {
my $self = shift;
my $name = shift;
if ( defined $name ) {
$self->{NAME} = $name;
}
return $self->{NAME};
}
sub occupation {
my $self = shift;
my $occupation = shift;
if ( defined $occupation ) {
$self->{OCCUPATION} = $occupation;
}
return $self->{OCCUPATION};
}
package Developer;
use parent -norequire, qw(Person);
sub programming_language {
my $self = shift;
my $language = shift;
if ( defined $language ) {
$self->{LANGUAGE} = $language;
}
return $self->{LANGUAGE};
}
可以使用SUPER
类强制子类使用超类定义:
我本可以定义一个new
子程序,......呃... 方法,...不,呃... 我的Developer类中的构造函数 :
package Developer;
...
sub new {
my $class = shift;
my $name = shift;
my $language = shift;
my $occupation = "Code Slinger";
my $self = {};
bless $self, $class; # Defines a Developer or subclass object
$self->SUPER::name($name); # Sets the name of my Developer
$self->SUPER::occupation($occupation); # We know the occupation
return $self;
}
现在,如果我请求$me->occupation
,它将返回Code Slinger
。