- Perl ›
- Object Oriented ›
- 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