Perl继承和方法解析

示例

要使一个类成为另一个类的子类,请使用parent编译指示:

package Point;
use strict;
...
1;

package Point2D;
use strict;
use parent qw(Point);
...
1;

package Point3D;
use strict;
use parent qw(Point);
...
1;

Perl允许多重继承:

package Point2D;
use strict;
use parent qw(Point PlanarObject);
...
1;

继承是关于在特定情况下要调用哪种方法的解析。由于纯Perl并未规定有关用于存储对象数据的数据结构的任何规则,因此继承与之无关。

考虑以下类层次结构:

package GeometryObject;
use strict;

sub transpose { ...}

1;

package Point;
use strict;
use parent qw(GeometryObject);

sub new { ... };

1;

package PlanarObject;
use strict;
use parent qw(GeometryObject);

sub transpose { ... }

1;

package Point2D;
use strict;
use parent qw(Point PlanarObject);

sub new { ... }

sub polar_coordinates { ... }

1;

方法解析如下:

  1. 起点由箭头运算符的左操作数定义。

    • 如果只是一个简单的词:

      Point2D->new(...);

      ...或包含字符串的标量变量:

      my $class = 'Point2D';
      $class->new(...);

      ...然后起点是具有相应名称的软件包(Point2D在两个示例中)。

    • 如果左操作数是一个标量变量,该标量变量包含一个有福的引用:

      my $point = {...};
      bless $point, 'Point2D'; # typically, it is encapsulated into class methods
      my @coord = $point->polar_coordinates;

      那么起点就是参考的类别(再次,Point2D)。箭头运算符不能用于调用无祝福引用的方法。

  2. 如果起点包含必需的方法,则将其简单调用。

    因此,既然Point2D::new存在,

    Point2D->new(...);

    会简单地称呼它。

  3. 如果起点不包含必需的方法,则在parent类中执行深度优先搜索。在上面的示例中,搜索顺序如下:

    例如,在以下代码中:

    my $point = Point2D->new(...);
    $point->transpose(...);

    GeometryObject::transpose即使会被覆盖,也会被调用的方法是PlanarObject::transpose。

    • Point2D

    • Point(的第一位父母Point2D)

    • GeometryObject(的父母Point)

    • PlanarObject(的第二个父级Point2D)

  4. 您可以显式设置起点。

    在前面的示例中,您可以PlanarObject::transpose像这样显式调用:

    my $point = Point2D->new(...);
    $point->PlanarObject::transpose(...);
  5. 以类似的方式,SUPER::在当前类的父类中执行方法搜索。

    例如,

    package Point2D;
    use strict;
    use parent qw(Point PlanarObject);
    sub new {
       (my $class, $x, $y) = @_;
       my $self = $class->SUPER::new;
       ...
    }
    1;

    将Point::new在执行过程中调用Point2D::new。