当父母的内部表示未知时,如何派生子类?

时间:2018-01-18 06:33:06

标签: perl oop

从其他人编写的类中派生类的最佳方法是什么,以及哪些内部表示(即其对象哈希)必须假定为未知?我看到的问题是显而易见的方式:

package Employee;
use parent 'Person';    # inherits from Person

# Override constructor
sub new {
    my ($class, $first_name, $last_name, $id, $title) = @_;

    # Call the constructor of the parent class, Person.
    my $self = $class->SUPER::new( $first_name, $last_name );
    # Add few more attributes
    $self->{id}   = $id;  # <-- I cannot know if 'id' is already used by parent
    $self->{title} = $title; # <-- same here: 'title' might be in use
    return bless $self, $class;
}

遇到的问题是父项的$self哈希值必须假定为黑盒子(即使我们今天知道了表示(属性)),我们也无法知道模块的作者是否会在未来)。然后,如果孩子尝试将自己的属性插入$self哈希,它可能会覆盖具有相同名称的父属性。

2 个答案:

答案 0 :(得分:2)

可以使用&#34;由内而外的对象&#34;为了这。即使您对父类的对象表示一无所知,但至少可以依靠的一件事是每个对象都是引用。这意味着,因为每个引用都有一个唯一的refaddr,您可以将对象的自己的属性存储在哈希中,由对象的refaddr键入,并且永远不必放置任何内容&#34; #34;完全是对象。

可以自己正确地执行此操作,但如果您不熟悉详细信息,则有点棘手,因此我建议您在子类中使用MooseX::NonMoose::InsideOutMooX::InsideOut来执行此操作你。

答案 1 :(得分:1)

以下是使用OVERLOAD()和对象组合的可能解决方案:

package Employee;
use Person;

sub new {
    my ($class, $first_name, $last_name, $id, $title) = @_;

    my $parent = Person->new( $first_name, $last_name );
    my $self = { 
        parent => $parent, id => $id, title => $title
    };
    return bless $self, $class;
}

sub AUTOLOAD {
    my ( $self, @args ) = @_;
    our $AUTOLOAD;
    my $sub_name = $AUTOLOAD;
    $sub_name =~ s/^Employee:://;
    my $parent = $self->{parent};
    my $parent_sub = $parent->can( $sub_name );
    if ($parent_sub ) {
        return $parent_sub->( $parent, @args);
    }
}

# More child methods follows here..
1;