【问题标题】:Is there an actual derived class at runtime in Perl?Perl 在运行时是否有实际的派生类?
【发布时间】:2013-09-29 11:04:51
【问题描述】:

我正在研究 Perl OO(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); 

结果:

时间:2013 年 9 月 29 日星期日 12:56:29

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

问题:为什么转储中报告的对象是 Obj::Employee 而不是 Obj::Manager?
我打电话给新的经理。

【问题讨论】:

  • 顺便说一下,由于方法get_startedset_started是实例方法(不像new是类方法),它们的第一个参数将是类的实例,不是班级本身。所以你应该叫它$self 或其他名称以避免混淆。
  • Objs::Employee 中的 $started 包变量未使用。

标签: perl oop perl-module activestate


【解决方案1】:

始终为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

如果派生类可能继承执行祝福的函数,请始终使用双参数版本

【讨论】:

  • 为什么?能详细说明一下吗?
  • 在我的示例中,$class 是一个传入的参数,我希望它是 Manager,因为我这样做了:Objs::Manager->new。所以$self 但它本身就是超级构造函数返回的,它是一个 Employee 并且 bless 将它向下转换?
  • 类始终是构造函数中的第一个参数(静态方法)。当从子类调用时,则传递子类,否则为当前类。请注意,您的孩子和父母内部的$class 是具有不同值的不同变量。
  • 即使在对Objs::Employee->new 的调用中$classObjs::Manager(我没有争议),这也是一个有争议的问题,因为你还没有使用过$class。但是因为您没有使用bless 的第二个参数,所以它默认为当前包,由package Objs::Employee; 行设置。
猜你喜欢
  • 2010-12-13
  • 2013-07-05
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
  • 2023-03-31
  • 2021-04-14
相关资源
最近更新 更多