2013-09-29 27 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'是具有不同值的不同變量。 –

相關問題