package Point;
use Moose;
has 'x' => (isa => 'Int', is => 'rw', required => 1);
has 'y' => (isa => 'Int', is => 'rw', required => 1);
sub clear {
my $self = shift;
$self->x(0);
$self->y(0);
}
package Point3D;
use Moose;
extends 'Point';
has 'z' => (isa => 'Int', is => 'rw', required => 1);
after 'clear' => sub {
my $self = shift;
$self->z(0);
};
....
# hash or hashrefs are ok for the constructor
my $point1 = Point->new(x => 5, y => 7);
my $point2 = Point->new({x => 5, y => 7});
my $point3d = Point3D->new(x => 5, y => 42, z => -5);
和perl5里面非常相似,类都放在一个声明的package里面,use Moose自动为我们添加use strict和use Waring,同时导入缺省的函数和关键字,并自动创建构造器
第一个关键字
has 'x' => (isa => 'Int', is => 'rw', required => 1);
为类创建一个名为x的属性,isa代表这是一个Int类型的变量,rw代表可读写,required代表创建类的实例的时候,必须提供这个变量值。
之后可以创建类的方法了,它只是一个子函数而已
sub clear {
my $self = shift;
$self->x(0);
$self->y(0);
}
借着来我们定义了子类Point3D,在子类中通过关键字extend来声明父类
extends 'Point';
extends和use base的功能很像,但有点不同的是extends覆盖了@ISA数组,而use base是把参数添加到@ISA数组
接下来创建类Point3D的新属性x
has 'z' => (isa => 'Int', is => 'rw', required => 1);
这和x,y没什么区别
after关键字声明了Moose的一个特性:方法修改器
after 'clear' => sub {
my $self = shift;
$self->z(0);
};
当从类Point3D中调用clear是,这个定义的函数会运行,之所以称为关键字after,是由于这个修改器在真正定义的函数后在被调用的。
从某种意义上来说这就是一个函数的继承
我们当然还有其他的方法做到这些,因为这是"perl"
比如:
sub clear {
my $self = shift;
$self->SUPER::clear();
$self->z(0);
}
再比如使用关键字override
override 'clear' => sub {
my $self = shift;
super();
$self->z(0);
};
据说是可以让你像ruby一样使用父类函数,可惜不懂ruby
然后就可以使用我们所写的类了
my $point1 = Point->new(x => 5, y => 7);
my $point2 = Point->new({x => 5, y => 7});
my $point3d = Point3D->new(x => 5, y => 42, z => -5);
注意:Moose里面的类都是一个hasn引用
所谓脚注:
1:Moose定义的数据类型
很多,去这里看 Moose::Util::TypeConstraints
2:Moose的extends支持多重继承
3:没看太懂,大约是使用某种方法Moose可以支持非hashref类型的类
文档支持在这里 Moose::Util::TypeConstraints

没有评论:
发表评论