Perl 继承 - 子程序覆盖

标签 perl inheritance

有没有办法用新的行为(两个类相同)覆盖 class_1_1class_2_1 中的 sub a 而不添加被覆盖的class_1_1class_2_1 的方法?

package class_0
    sub a
    sub b
1;

package class_1 
    use parent 'class_0'
    sub b
1;

package class_2
    use parent 'class_0'
    sub b
1;

package class_1_1
    use parent 'class_1'
1;

package class_2_1
    use parent 'class_2'
1;  

最佳答案

一个量身定制的解决方案是添加 role对于想要的行为。

这是一个带有 native OO 代码的示例,使用独立的 Role::Tiny对于角色

use warnings;
use strict;

use SomeClass;

my $obj = SomeClass->new;

$obj->a_method;

SomeClass.pm

package SomeClass;

use warnings;
use strict;
use feature 'say';

use Role::Tiny::With;  # To "consume" a role. Comes with Role::Tiny

# Consume roles from "AddedRoles.pm"
# That may add or require methods, or override the ones here
with 'AddedRoles';     

sub new { bless { }, $_[0]] }

sub a_method { say "From ", __PACKAGE__ }

1;

这个角色也可以添加到其他类中,方法是添加 use 语句和行 with 'AddedRoles'; 到它们,不管它们的继承关系如何。有关微调流程的方法,请参阅文档。

带有角色的包,AddedRoles.pm

package AddedRoles;

use feature 'say';  # we get strict and warnings from the package but not this

use Role::Tiny;

# Require that consumers implement methods; Add a method
#require method_1, method_2;    
#sub added_method { say "Adding functionality to consumers" }

# Replace "a_method" in a consumer
around a_method => sub { say "From an overriding role ", __PACKAGE__ } 

1;

Role::Tiny 需要安装(没有依赖)。 要替换在使用角色的类中定义的方法,我们需要一个 方法修饰符 around,Class::Method::Modifiers 提供,所以这是一个额外的依赖。

角色经常被比作继承,并声称提供了一个更好、更轻便的替代方案,因为继承通常被“烘焙”到整个类层次结构等中。然而,继承通常专门行为,而角色很明显更灵活;他们添加或修改行为(或者可以专门针对此问题)。我宁愿看到角色在继承和组合之间很合适。

请注意,使用角色,我们可以拥有几乎等同于多重继承的功能,而几乎没有任何令人生畏的(和令人生畏的)令人头疼的问题。

上面的简单示例演示了 Role::Tiny 的使用。但是角色最好与 MooseMoo 框架一起使用,使用 Moose::RoleMoo:Role .

我绝对建议研究这些框架。我坚信学习如何使用 Perl 的 native OO 系统的值(value),但一旦掌握了这些,不尝试 MooseMoo.


在这个特定的问题中,虽然要覆盖的方法是从另一个类继承,在这种情况下不需要修饰符。来自 "Role Composition" in docs

If a method is already defined on a class, that method will not be composed in from the role. A method inherited by a class gets overridden by the role's method of the same name, though.

所以在这个问题的情况下,通常在角色包中定义一个子就足够了

# In the package that defines roles (like 'AddedRoles' above)
sub a_method  { say "From an overriding role ", __PACKAGE__ } 

当这个角色被一个继承 a_method的类使用时,比如问题中的class_1_1,这个方法确实被这个覆盖了一个。

请注意,如果一个方法在类中定义本身(未继承),那么定义为普通 sub 的角色会被忽略(它不会覆盖方法,它不会发出警告等)。

另一方面,around 在任何一种情况下都会覆盖一个方法(继承或在类中定义),但不能添加根本不存在的方法(如果那样的话会抛出异常已尝试)。

关于Perl 继承 - 子程序覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63585871/

相关文章:

arrays - 数组哈希中缺少零

python - 使用 Perl TK 或 Python Tkinter 的自定义窗口

perl - 如何在 Perl 中读取 Excel 文件?

java - 抽象类中的静态方法

php - 在 PHP 中的子构造函数之前调用父构造函数

xml - 使用 Perl 的 XML 标签内的总和和平均值

perl - 如何使用 perl 根据条件将行拆分为数组?

C++ 表达式模板——为什么是基类?

c++ - 抽象类,如何调用函数print

c# - 使用泛型和 'new' 修饰符隐藏父成员时的 C# 继承问题