Perl 中的重写方法是什么? [英] What is an overriden method in Perl?
问题描述
这个问题是关于 SUPER
类的.
This question is about the SUPER
class.
什么时候会发生覆盖方法"?
When would an "overridden method" happens?
所以说当我实例化一个类时:
So say when I instantiate a class:
$object = Classname -> new (some => 'values');
这就是所谓的重写方法吗?新方法的覆盖值?
Is that what you call an overridden method? the new method's overridden values?
如果是这样,我为什么要使用那个 SUPER
类?
If so then, why would I want to use that SUPER
class?
我只能说:
$object = Classname -> new ();
我又有了原来的方法.有人可以为我澄清一下吗?
I have the original method again. Can someone clarify this for me?
推荐答案
继承描述了父子关系.父母可以做的一切,孩子班级也可以.例如
Inheritance describes a parent-child relationship. Everything the parents can do, the child class can too. E.g.
ParentA ParentB
======= =======
foo() foo()
------- bar()
| -------
| /
Child
=====
此 UML 图显示 Child
继承自 ParentA
和 ParentB
,例如通过代码
This UML diagram shows that Child
inherits from ParentA
and ParentB
, e.g. via the code
package Child;
use parent "ParentA";
use parent "ParentB"
现在,Child
继承了 ParentA
的方法 foo
和 ParentB
的 bar
代码>.
Now, Child
has inherited the method foo
from ParentA
and bar
from ParentB
.
如果 Child
自己定义了一个 foo
方法,Child->foo
会调用这个方法,不会 父类的方法之一.然后说foo
方法被覆盖.
If Child
defines a foo
method itself, Child->foo
would call this method, and not one of the methods of the parent classes. It is then said that the foo
method is overridden.
在子类化时,重用父类的构造函数通常很有用.但有时,必须进行额外的处理.在这种情况下,子类想要提供不同的默认参数:
When subclassing, it is often useful to re-use the constructor of the parent. But sometimes, additional processing has to be done. In this case, a subclass wants to provide a different default argument:
马.pm
package Horse;
use strict; use warnings;
sub new {
my ($class, %args) = @_;
return bless {
legs => 4,
saddled => 0,
%args,
} => $class;
}
1;
SaddledHorse.pm
SaddledHorse.pm
package SaddledHorse;
use strict; use warnings;
use parent 'Horse';
# This override the inherited "new"
sub new {
my ($class, %args) = @_;
# the "SUPER" pseudo-package points to the parent
return $class->SUPER::new(%args, saddled => 1);
}
1;
注意 $class
是如何传播的,以将引用添加到正确的类中.SUPER
包仅在定义继承关系的包内可用,并且可以说是被破坏的.如果你需要SUPER
,你通常会想使用Moose,其中明确说要覆盖的方法可以通过super
函数调用super方法.
Note how the $class
is propagated to bless the reference into the correct class. The SUPER
package is only available inside a package that defines an inheritance relationship, and is arguably broken. If you need SUPER
, you usually want to use Moose, where a method that is explicitly said to override can call the super method with the super
function.
如果您在包/对象上调用方法,则在运行时解析正确的方法.如果您查看继承图的这个答案的顶部,您可以看到 ParentB
定义了 bar
.如果我们在 Child
上调用 bar
方法,则会查找该方法
If you call a method on a package/object, the correct method is resolved at runtime. If you look at the top of this answer to the inheritance diagram, you can see that ParentB
defines bar
. If we invoke the bar
method on a Child
, that method is looked for
- 在
子
中, - 在
ParentA
中,和 - 在
ParentB
中,它所在的位置.
- in
Child
, - in
ParentA
, and - in
ParentB
, where it is found.
这称为方法解析",本身就是一个棘手的问题.
This is called "method resolution", and is a tricky issue in itself.
如果我们传递一个完全限定的子程序名称作为方法,则不会发生解析,直接调用子程序.例如.Child->foo
会将方法解析为 ParentA::foo
,因此该调用将大致等于 ParentA::foo("Child")代码>.如果我们这样做
If we pass a fully qualifed subroutine name as the method, no resolving happens, and the sub is called directly. E.g. Child->foo
would resolve the method to ParentA::foo
, so that call would be roughly equal to ParentA::foo("Child")
. If hower we do
Child->ParentB::foo();
我们得到了ParentB::foo("Child")
的效果.带有 ->
的语法是多余的,但提醒我们我们正在使用对象上的方法.因此,我更喜欢写
we get the effect of ParentB::foo("Child")
. The syntax with the ->
is superfluous, but reminds us that we are kind of using a method on an object. Therefore, I preferred to write
$class->SUPER::new(%args, saddled => 1)
在SaddledHorse
示例中,即使这只是
in the SaddledHorse
example, even if this is only elaborate syntax for
# SUPER::new($class, %args, saddled => 1) # pseudocode, won't actually run
解析为
Horse::new($class, %args, saddled => 1)
这篇关于Perl 中的重写方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!