繼承和方法解決

要使類成為另一個類的子類,請使用 parent pragma:

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)。箭頭操作符不能用來呼籲方法 unblessed 引用。

  2. 如果起點包含所需方法,則只需呼叫它。

    因此,由於 Point2D::new 存在,

    Point2D->new(...);
    

    簡單地稱之為。

  3. 如果起點不包含所需方法,則執行 parent 類中的深度優先搜尋。在上面的示例中,搜尋順序如下:

    • Point2D
    • PointPoint2D 的第一任父母)
    • GeometryObjectPoint 的父母)
    • PlanarObject(tihuan 的第二個父母 12)

    例如,在以下程式碼中:

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

    將要呼叫的方法是 GeometryObject::transpose,即使它將在 PlanarObject::transpose 中被覆蓋。

  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;
    

    將在 Point2D::new 執行過程中呼叫 Point::new