Perl 5.38新class语法下子类向父类构造传参的实现方法
Perl 5.38.x 子类向父类注入构造参数的实现方法
在Perl 5.38.x的核心class语法(基于Object::Pad)中,无法通过BUILD方法修改父类的构造参数——因为BUILD是在对象完成初始化(包括父类参数绑定)后才执行的。要实现Square类通过side参数向父类Rectangle注入length和height,需使用BUILDARGS方法预处理构造参数。
正确代码实现
修正后的类定义
class Rectangle { field $length :param; field $height :param; method get_area { return $length * $height; } } class Square :isa(Rectangle) { # 若无需在子类中保留side值,可省略此字段及后续BUILD方法 field $side; # 重写BUILDARGS转换构造参数 method BUILDARGS (%args) { return ( length => $args{side}, height => $args{side}, side => $args{side} # 传递给子类自身的BUILD方法 ); } BUILD (%args) { $side = $args{side}; } # 可选:暴露side属性的方法 method get_side { return $side; } }
测试脚本
my($rect) = Rectangle->new(length => 5, height => 6); say $rect->get_area(); my($sq) = Square->new(side => 5); say $sq->get_area();
输出结果
30 25
简化版实现(无需保留side字段)
如果不需要在Square类中存储side值,可进一步简化:
class Square :isa(Rectangle) { method BUILDARGS (%args) { return (length => $args{side}, height => $args{side}); } }
原代码无效原因
原代码中的BUILD方法执行时机晚于父类的参数绑定过程,此时修改@_无法影响父类$length和$height的初始化,导致这两个字段为undef,计算面积时得到错误结果。
内容的提问来源于stack exchange,提问作者Joe Casadonte
相关产品推荐
相关产品推荐

