Perl 中的重写方法是什么? [英] What is an overriden method in Perl?

查看:52
本文介绍了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 继承自 ParentAParentB,例如通过代码

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 的方法 fooParentBbar代码>.

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

  1. 中,
  2. ParentA中,和
  3. ParentB 中,它所在的位置.
  1. in Child,
  2. in ParentA, and
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆