-1

SUPERクラスについての質問です。

「オーバーライドされたメソッド」はいつ発生しますか?

クラスをインスタンス化するときは、次のように言います。

$object = Classname -> new (some => 'values');

それはあなたがオーバーライドされたメソッドと呼んでいるものですか?新しいメソッドのオーバーライドされた値?

SUPERもしそうなら、なぜそのクラスを使いたいのでしょうか?

私はただ言うことができます:

$object = Classname -> new ();

私は再び元の方法を持っています。誰かが私のためにこれを明確にすることができますか?

4

2 に答える 2

3

Inheritance describes a parent-child relationship. Everything the parents can do, the child class can too. E.g.

ParentA    ParentB
=======    =======
foo()      foo()
-------    bar()
     |     -------
     |   /
    Child
    =====

This UML diagram shows that Child inherits from ParentA and ParentB, e.g. via the code

package Child;
use parent "ParentA";
use parent "ParentB"

Now, Child has inherited the method foo from ParentA and bar from ParentB.

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.

Example

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:

Horse.pm

package Horse;
use strict; use warnings;

sub new {
  my ($class, %args) = @_;
  return bless {
    legs => 4,
    saddled => 0,
    %args,
  } => $class;
}

1;

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;

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.

Edit: A note on fully qualifed method names

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. 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.

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();

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)

in the SaddledHorse example, even if this is only elaborate syntax for

# SUPER::new($class, %args, saddled => 1)  # pseudocode, won't actually run

which resolves to

Horse::new($class, %args, saddled => 1)
于 2013-06-19T08:54:57.173 に答える