2013-09-29 28 views
7

我正在研究Perl OO(Perl新手)。我创建了一个简单的例子层次:
父类:Perl在运行时是否有实际的派生类?

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

package Objs::Employee; 

my $started; 

sub new { 
    my ($class) = @_; 
    my $cur_time = localtime; 
    my $self = { 
     started => $cur_time, 
    }; 
    print "Time: $cur_time \n"; 
    bless $self; 
} 

sub get_started { 
    my ($class) = @_; 
    return $class->{started}; 
} 

sub set_started { 
    my ($class, $value) = @_; 
    $class->{started} = $value; 
} 

1; 

子类:

#!/usr/bin/perl 
package Objs::Manager; 
use strict; 
use warnings; 

use base qw (Objs::Employee); 

my $full_name; 

sub new { 
    my ($class, $name) = @_; 
    my $self = $class->SUPER::new(); 
    $self->{full_name} = $name; 
    return $self;  
} 

1; 

我尝试按如下测试:

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


use Objs::Manager; 

my $emp = Objs::Manager->new('John Smith'); 
use Data::Dumper; 
print Dumper($emp); 

结果:

时间:Sun Sep 29 12:56:29 2013

$VAR1 = bless({ 
       'started' => 'Sun Sep 29 12:56:29 2013', 
       'full_name' => 'John Smith' 
       }, 'Objs::Employee'); 

问题:为什么转储中报告的对象是Obj :: Employee而不是Obj :: Manager?
我在Manager上调用了new。

+1

顺便说一句,因为'get_started'和'set_started'方法是实例方法(unli ke'new'是一个类方法),它们的第一个参数将是类的一个实例,而不是类本身。所以你应该称之为'$ self'或者其他的东西来避免混淆。 –

+0

Objs :: Employee中的$ started包变量未使用。 –

回答

11

对于bless,请始终使用两个参数,因为$class会告知哪些包应该受到祝福。如果省略$class,则使用当前包。

bless $self, $class; 

输出

$VAR1 = bless({ 
      'started' => 'Sun Sep 29 13:24:26 2013', 
      'full_name' => 'John Smith' 
      }, 'Objs::Manager'); 

perldoc -f bless

始终使用两个参数的版本,如果一个派生类可以继承的功能做祝福

+0

为什么?请您详细说明一下? – Cratylus

+0

在我的例子中,'$ class'是一个传入的参数,我期望它是Manager,因为我做过:'Objs :: Manager-> new'。所以'$ self'本身就是超级构造函数返回的东西,这是一个Employee,并且保佑它是downcasts呢? – Cratylus

+0

类始终是构造函数(静态方法)中的第一个参数。当从小孩调用时,子类被传递,否则它是当前类。请注意,您的子项和父项中的'$ class'是具有不同值的不同变量。 –

相关问题