Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

If so then, why would I want to use that SUPER class?

I can just say:

$object = Classname -> new ();

I have the original method again. Can someone clarify this for me?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
120 views
Welcome To Ask or Share your Answers For Others

1 Answer

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...