1. Perl
  2. Object Oriented
  3. Polymorphism

Polymorphism with inheritance

One of the characteristics of object orientation is polymorphism. Polymorphism can be understood in the sense that similar descriptions behave differently .

1. Make different behaviors depending on the class

Now, let's write an example that behaves differently depending on the class to which you belong. A simple example is to concatenate strings with specific symbols. The Unix delimiter and the Windows delimiter are treated as examples.

use strict;
use warnings;

my $file_path_unix = FilePath::Unix->new;
my $file_path_win = FilePath::Windows->new;

my $unix_result = $file_path_unix->cat_path('a', 'b');
my $win_result = $file_path_win->cat_path('a', 'b');

print "unix: $unix_result\n";
print "win: $win_result\n";

# Base class for handling file paths
package FilePath::Base;
sub new {
  my $proto = shift;
  my $class = ref $proto || $proto;
  my $self = {};
  bless $self, $class;
  return $self;
}

sub cat_path {
  my ($self, $str1, $str2) = @_;
  return $str1. $Self->delimiter. $Str2;
}


# For Unix
package FilePath::Unix;
use base 'FilePath::Base';

# Unix delimiter
sub delimiter {return'/'}

# For Windows
package FilePath::Windows;
use base 'FilePath::Base';

# Delimiter for Windows
sub delimiter {return'\\'}

When you run this example

unix: a/b
win: a\b

It will be displayed.

2. Pay attention to the behavior of cat_path

First of all, the characteristic of this example is that the method called cat_path has two meanings.

package FilePath::Base;
sub new {...}

sub cat_path {
  my ($self, $str1, $str2) = @_;
  return $str1. $Self->delimiter. $Str2;
}

If you look at the class FilePath::Base, there is a method called cat_path. By the way, if you look at the part that calls cat_path, the object of File::Path class is not created.

my $file_path_unix = FilePath::Unix->new;
my $file_path_win = FilePath::Windows->new;

my $unix_result = $file_path_unix->cat_path('a', 'b');
my $win_result = $file_path_win->cat_path('a', 'b');

Objects of the FilePath::Unix class and FilePath::Windows class have been created, respectively.

This is because FilePath::Unix and FilePath::Windows inherits his FilePath::Base, as explained in Inheritance. , FilePath::I was able to call the method of the Base class, cat_path.

The next thing to pay attention to is the description of $self->delimiter in cat_path.

3. Call a subclass method in the superclass.

Let's pay attention to the inside of cat_path.

sub cat_path {
  my ($self, $str1, $str2) = @_;
  return $str1. $Self->delimiter. $Str2;
}

In cat_path, the delimiter method is called. However, FilePath::Base does not have a method called delimiter. Can I call a method I don't have?

Actually, there is a secret in this $self part.

my $unix_result = $file_path_unix->cat_path('a', 'b');

When you call the cat_path method like this, the object assigned to $self is the FilePath::Unix class object.

The FilePath::Unix class has a delimiter method, so you can call the delimiter method from within the cat_path method.

4. The FilePath::Base class is an incomplete class that is intended to be inherited.

If you create an object of the FilePath::Base class, cat_file will fail if you try to call the delimiter method internally.

my $file_path_base = FilePath::Base->new;
$file_path_base->cat_file('a', 'b'); # Failure!

A class that implements the delimiter method that inherits the FilePath::Base class will be created and meaningful.

I would like to name such a class inherited class . (I couldn't find a proper name for such a class in a Perl book, so I'll call it a inherited class . It's called a Java abstract class because it can create objects. Not really)

5. Defining methods in subclasses

And notice that the FilePath::Unix class and the FilePath::Windows class have different implementations of the delimiter method to achieve polymorphism.

# FilePath::Unix class
sub delimiter {return'/'}
# FilePath::For Windows class
sub delimiter {return'\\'}

This description is the part that substantially changes the behavior of the output result.

unix: a/b
win: a\b

Related Informatrion