This chapter introduced how to use Perl to program the (OOP) characteristic object-oriented and how to construct the object, but also includes inherits, contents and so on method heavy load and data encapsulation.
First, module synopsis
Module (module) is Perl wraps (pachage). In Perl object based on to package in data item quotation. (quotation sees the xth chapter of quotation).
For details sees http://www.metronet.com/’s perlmod and perlobj.
When uses other languages carry on the object-oriented programming, first stated a kind then founds this kind of object (example), the specific kind of all object’s behavior way is the same, determined by a kind of method, may through define the new kind or inherit the foundation class from the extant kind. The familiar object-oriented programming’s person has been possible to meet many familiar terminology in this. Perl has been an object-oriented language, in Perl5, the grammar slightly has the change, has standardized the object use.
Following three define to understood that the object, how kind and the method does work very important in Perl.
. The kind is a Perl package, contains provides the object method the kind.
. The method is a Perl subroutine, a kind of name is its first parameter.
. The object is to the kind of data item quotation.
Second, in Perl kind
Emphasizes again, one Perl kind is only a package. When you saw in the Perl documents mentioned when “kind”, regarded as “the package” it to be good. The Perl5 grammar may the foundation class, if your already familiar C++, then the majority of grammars you already grasped. With the Perl4 different concept is with the double colon (::)Marks the basic kind and inherits the kind (subclass).
An object-oriented important characteristic is inherits. In Perl inherits the characteristic to be not completely same as other object-oriented languages, it only inherits the method, you must realize data inheritance with your mechanism.
Because each kind is a package, therefore it has her name space and her symbolic name connection array (for details sees xth chapter of connection array), thus each kind may use own independent symbolic name collection. With the package of quotation union, may use the single quotes (‘) the instruction character localization class variable, kind of member’s localization form for example: $class’$member. In Perl5, the available double colon substitution single quotes obtain the quotation, for example: $class’$member and $class::$member are the same.
Third, foundation class.
This festival introduced that founds one new kind of essential step. The following use’s example is founds one to be called Cocoa the simple kind, its function is outputs a simple Java application the sound code essential part. Felt relieved that this example does not need you to have the Java knowledge, but will not cause you to become the Java expert, its goal narrates the foundation class concept.
First, founds named Cocoa.pm the package document (extension pm is package’s default extension, Italy is Perl Module). A module is a package, a package is one kind. Before doing other matters, joins first 1 ” such line, when you increase other lines, remembers the retention “1; ” is the last line. This is a Perl package of essential condition, otherwise this package not by the Perl processing. Below is this document basic structure.
package Cocoa;
#
# Put “require” statements in for all required, imported packages
#
#
# Just add code here
#
1; # terminate the package with the required 1;
Then, we increase the method toward the package to cause it to become one kind. Must first increase the method is new(), it is founds when the object must transfer, the new() method is the object structure function.
Fourth, structure function
The structure function is a kind of subroutine, it returns to and a kind of name related quotation. A kind of name and the quotation will unify are called the blessing” an object, because will establish this union function named bless(), its grammar will be:
bless YeReference [, classname]
YeReference is to the quilt “the blessing” the object quotation, classname is may the option, assigns the object gain method Bao Ming, its default value for current package name.
Founds a construction function the method for the returns already and this kind of union internal structure quotation, for example:
sub new {
my $this = {}; # Create an anonymous hash, and #self points to it.
bless $this; # Connect the hash to the package Cocoa.
return $this; # Return the reference to the hash.
}
1;
{} founds one to not including the key/value to Hasche table (i.e. connection array) the quotation, the returns value is bestowed on for confined variable $this. Function bless() takes out this quotation, the one who tells the object it to quote is Cocoa, finally returns to this quotation. The function returns value aims at this anonymous Hasche table now.
After new() function returns, the $this quotation is destroyed, but the transfer function has preserved to this Hasche table quotation, therefore this Hasche table’s quotation number cannot be zero, thus causes Perl to guarantee the debit and credit Hasche table in the memory. The foundation object may transfer as follows:
$cup = new Cocoa;
The following sentence to use this package foundation object the example:
1 #! /usr/bin/perl
2 push (@INC, ‘pwd’);
3 use Cocoa;
4 $cup = new Cocoa;
The first line pointed out that the Perl interpreter’s position, in the second line, adds to the current directory the way to seek tabulates in @INC for to seek time the package uses. You may also found your module in the different table of contents and point out this absolute way. For example, if in the /home/test/scripts/ foundation package, the second line should be as follows:
push (@INC, “/home/test/scripts”);
In the third line, contains on wraps Cocoa.pm to gain in the script to need the function. the use sentence tells Perl, in the @INC way seeks for document Cocoa.pm and contains to the analysis source document copy. the use sentence is the use class must. The fourth line transfers the new function foundation object, this is the Perl interesting part of it, is also place of its easy confusion, is also its formidable place. The foundation object’s method has many kinds, may write like this:
$cup = cocoa->new();
If you are the C programmer, may use the double colon to force to use Cocoa package of the new() function, for example:
$cup = Cocoa::new();
May join more codes in the structure function, if in Cocoa.pm, may in each object foundation time outputs a simple statement, but may also use the structure function initialization variable either the establishment array or the indicator.
Attention:
1st, certainly must in the structure function the initialization variable;
2nd, certainly must use the my function to found the variable in the method
3rd, certainly do not use local in the method, only if really wants to transmit the variable for other subroutines
4th, certainly do not use the global variable in a kind of module.
In addition the statement Cocoa structure function is as follows:
sub new {
my $this = {};
print n/* n ** Created by Cocoa.pm n ** Use at own risk”;
print “n ** Did this code even get pass the javac compiler? ”;
print “n **/n”;
bless $this;
return $this;
}
May also transfer Bao Neihuo package of outside other functions to do the more initialization work simply, for example:
sub new {
my $this = {}
bless $this;
$this->doInitialization();
return $this;
}
When foundation class, should allow it to be possible to inherit, should be possible to tra
nsfer a kind of celebrated work for the first parameter the new function, then the new function looks like the following sentence:
sub new {
my $class = shift; # Get the request class name
my $this = {};
bless $this, $class # Use class name to bless() reference
$this->doInitialization(); return $this;
}
This method enables the user to be possible one of following three ways to carry on the transfer:
Cocoa::new()
Cocoa->new()
new Cocoa
May many times a bless quotation object, however, new will have been removed inevitably by the bless kind the object by the bless quotation, to C and the Pascal programmer, this looks like an indicator bestows on for an assignment memory, bestows on again the identical indicator for in addition together the memory, but before does not release, together the memory. In brief, a Perl object each time can only belong to one kind.
What the object and is the quotation true difference? The Perl object by belongs to by bless some kind, the quotation is not so, if quotes by bless, it will belong to one kind, also has then become the object. The object knew that which kind he does belong to, the quotation does not belong to any kind.
Instance variable
As structure function new() function parameter named instance variable. Instance variable when foundation object each example uses in the initialization, for example may use the new() function to give a name the character for object each example.
May use the anonymous Hasche table or the anonymous array preserves the instance variable.
Is as follows with the Hasche table’s code:
sub new {
my $type = shift;
my %parm = @_;
my $this = {};
$this-> {‘Name’} = $parm {‘Name’};
$this-> {‘x’} = $parm {‘x’};
$this-> {‘y’} = $parm {‘y’};
bless $this, $type;
}
The code which preserves with the array is as follows:
sub new {
my $type = shift;
my %parm = @_;
my $this = [];
$this->[0] = $parm {‘Name’};
$this->[1] = $parm {‘x’};
$this->[2] = $parm {‘y’};
bless $this, $type;
}
When constructs the object, may transmit the parameter as follows:
$mug = Cocoa:: new (‘Name’ => ‘top’, ‘x’ => 10, ‘y’ => 20);
Instruction character => and the comma operation clothing function is the same, but the => readability is good. The access method is as follows:
print “Name=$mug-> {‘Name’} n”;
print “x=$mug-> {‘x’} n”;
print “y=$mug-> {‘y’} n”;
Fifth, method
A Perl kind of method just is a Perl subroutine, also namely usually called member function. The Perl method definition does not provide any special grammar, but the stipulation method’s first parameter or it is quoted for the object package. Perl has two methods: Static method and empty method.
The static method first parameter for a kind of name, the empty method first parameter for object quotation. The method processed the first parameter the way to decide it was the static state or empty. The static method neglects the first parameter generally, because they already knew that which kind they, the structure function were the static method. The empty method usually first first parameter shift to variable self or this, then makes this value the ordinary quotation use. For example:
1. sub nameLister {
2. my $this = shift;
3. my ($keys, $value);
4. while (($key, $value) = each (%$this)) {
5. print “t$key is $value.n”;
6. }
7. }
Sixth, method output
If you want to quote the Cocoa.pm package now, will obtain the compile error saying that has not found the method, this will be because the Cocoa.pm method has not output. The output method needs the Exporter module, adds on the following two lines in the package of start part:
require Exporter;
@ISA = qw (Exporter);
These two luggages contain the Exporter.pm module, and joins a Exporter kind of name the @ISA array to supply the search. Then yours kind of method row in the @EXPORT array might. For example wants to output method closeMain and declareMain, the sentence is as follows:
@EXPORT = qw (declareMain, closeMain);
Perl kind of inheritance is realizes through the @ISA array. the @ISA array does not need to define in any package, however, once it is defined, Perl regards as it the table of contents name the special array. It is similar with the @INC array, @INC is the included file seeks for the way. the @ISA array includes the kind (package), when a method has not found when the current package arrives in @ISA the package to seek. in @ISA also includes the base class name which the current kind inherits.
In the kind transfers all methods must belong to identical kind or the @ISA array define base class. If a method has not found in the @ISA array, Perl arrives in the AUTOLOAD() subroutine to seek, this may elect the subroutine defines in the current package with sub. If uses the AUTOLOAD subroutine, must use use Autoload; The sentence transfers the autoload.pm package. The method which the AUTOLOAD subroutine attempt from has installed in the Perl storehouse which loads transfers. If AUTOLOAD has also been defeated, Perl arrives at the UNIVERSAL kind to make the last attempt again, if were still defeated, Perl produces about should be unable the analytic function mistake.
Seventh, method transfer
Transfers an object the method to have two methods; first, through this object quotation (empty method); first, direct use class name (static method). Certainly this method must output. Now increases some methods for the Cocoa kind, the code is as follows:
package Cocoa;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw (setImports, declareMain, closeMain);
#
# This routine creates the references for imports in Java functions
#
sub setImports {
my $class = shift @_;
my @names = @_;
foreach (@names) {
print “import”. $ _. “; n”;
}
}
#
# This routine declares the main function in a Java script
#
sub declareMain {
my $class = shift @_;
my ($name, $extends, $implements) = @_;
print “n public class $name”;
if ($extends) {
print extends”. $extends;
}
if ($implements) {
print “implementsâ. $implements;
}
print “{n”;
}
#
# This routine declares the main function in a Java script
#
sub closeMain {
print } n”;
}
#
# This subroutine creates the header for the file.
#
sub new {
my $this = {};
print “n/* n ** Created by Cocoa.pm n ** Use at own risk n */n”;
bless $this;
return $this;
}
1;
Now, we write a simple Perl script to use this kind of method, below are found Java the applet source code skeleton’s script code:
#! /usr/bin/perl
use Cocoa;
$cup = new Cocoa;
$cup->setImports (‘java.io.In putStream’, ‘java.net.*’);
$cup->declareMain (“Msg”, “java.applet. Applet”, “Runnable”);
$cup->closeMain();
This section of scripts founded one to be called Msg Java applet, it expanded (extend) java.applet. The Applet small application procedure and causes it to be possible to move (runnable), the final three lines might also write as follows:
Cocoa:: setImports ($cup, ‘java.io.In putStream’, ‘java.net.*’);
Cocoa:: declareMain ($cup, “Msg”, “java.applet. Applet”, “Runnable”);
Cocoa::closeMain($cup);
Its movement result is as follows:
/*
** Created by Cocoa.pm
** Use at own risk
*/
import java.io.In putStream;
import java.net. *;
public class Msg extends java.applet. Applet implements Runnable {
}
Attention: If (is also called indirect transfer) with – > the instruction character transfer method, the parameter must use the parenthesis to include, for example: $cup->setImport
s (‘java.io.In putStream’, ‘java.net.*’); But double colon transfer for example: Cocoa:: setImports ($cup, ‘java.io.In putStream’, ‘java.net.*’); Might also remove the parenthesis to write: Cocoa::setImports $cup, ‘java.io.In putStream’, ‘java.net.*’;
Eighth, heavy load
Which kind of method sometimes needs to assign to use, if two different kinds have method time of the same name. Supposition class Espresso and Qava have defined method grind, may use:: The instruction character assigns to use Qava the method:
$mess = Qava:: grind (“whole”, “lotta”, “bags”);
Qava:: grind ($mess, âwhole”, “lotta”, “bags”);
Which kind of method can choose according to the procedure operational aspect uses, this may realize through the use mark quotation transfer:
$method = $local? “Qava:: ”: “Espresso:: ”;
$cup->{$method}grind(@args);
Ninth, analyzes the construction function
Perl track object link number, when some object’s last application releases the memory pond, this object automatically destroys. The object analyzes the construction to occur after the code stop, the script is going to end when. Speaking of the global variable, analyzes the construction to occur after the last line of code movement.
If you want before the object is released gains the domination, may define the DESTROY() method. DESTROY() before the object will release is transferred, enables you to be possible to do some clean-up. The DESTROY() function is not automatic transfers other DESTROY() function, Perl does not do built-in analyzes builds fortifications does. If the structure function bless, DESTROY() possibly needs to transfer other kind of DESTROY() function many times from the base class. When an object is released, among them contains all object quotation automatic release, destruction.
Generally speaking, does not need to define the DESTROY() function, if the need, its form is as follows:
sub DESTROY {
#
# Add code here.
#
}
Because many kinds of goals, Perl has used simply, based on the refuse reclamation system which quotes. Any object’s quotation number must be bigger than zero, otherwise this object’s memory is released. When procedure withdrawal, a Perl thorough search and destroys the function to carry on the refuse reclamation, in advancement is deleted simply. In a UNIX kind of system, this is likely unnecessary, but inlays in the type system or the multi-thread environment this is truly very essential.
Tenth, inherits
A kind of method inherits through the @ISA array, the variable inherits must be clear about the hypothesis. Founds two kind of Bean.pm and Coffee.pm as follows, Coffee.pm inherits Bean.pm some functions. How does this example demonstrate from the base class (or said that ultra kind) inherits the instance variable, its method to transfer base’s class structure function and add to own instance variable in the new object.
The Bean.pm code is as follows:
package Bean;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(setBeanType);
sub new {
my $type = shift;
my $this = {};
$this-> {‘Bean’} = ‘Colombian’;
bless $this, $type;
return $this;
}
#
# This subroutine sets the class name
sub setBeanType {
my ($class, $name) = @_;
$class-> {‘Bean’} = $name;
print “Set bean to $name n”;
}
1;
In this kind, establishes an anonymous Hasche table with the $this variable, ‘ Bean’leixing will suppose will be ‘ Colombian’。 method setBeanType() uses in changing ‘ Bean’leixing, it uses the $class quotation to obtain for the object Hasche table visit.
The Coffee.pm code is as follows:
1 #
2 # The Coffee.pm file to illustrate inheritance.
3 #
4 package Coffee;
5 require Exporter;
6 require Bean;
7 @ISA = qw (Exporter, Bean);
8 @EXPORT = qw (setImports, declareMain, closeMain);
9 #
10 # set item
11 #
12 sub setCoffeeType {
13 my ($class,$name) = @_
14 $class-> {‘Coffee’} = $name;
15 print “Set coffee type to $name n”;
16 }
17 #
18 # constructor
19 #
20 sub new {
21 my $type = shift;
22 my $this = Bean->new(); ##### < - LOOK HERE!!! ####
23 $this-> {‘Coffee’} = ‘Instant’; # unless told otherwise
24 bless $this, $type;
25 return $this;
26 }
27 1;
6th line of require Bean; The sentence has contained the Bean.pm document and all correlation functions, method setCoffeeType() uses in establishes confined variable $class-> {‘Coffee’} the value. In structure function new(), $this aims at the Bean.pm returns the anonymous Hasche table indicator, but is not in local founds one, following two sentences respectively be foundation different Hasche table, thus founds with the Bean.pm structure function the Hasche table has nothing to do with the situation and inherits situation:
my $this = {}; # must inherits
my $this = $theSuperClass->new(); # inherits
The following code demonstrates the method which how to transfer inherits:
1 #! /usr/bin/perl
2 push (@INC, ‘pwd’);
3 use Coffee;
4 $cup = new Coffee;
5 print “n ——————– Initial values ———— n”;
6 print “Coffee: $cup-> {‘Coffee’} n”;
7 print “Bean: $cup-> {‘Bean’} n”;
8 print “n ——————– Change Bean Type ———- n”;
9 $cup->setBeanType (‘Mixed’);
10 print “Bean Type is now $cup-> {‘Bean’} n”;
11 print “n —————— Change Coffee Type ———- n”;
12 $cup->setCoffeeType (‘Instant’);
13 print “Type of coffee: $cup-> {‘Coffee’} n”;
This code’s result output is as follows:
——————– Initial values ————
Coffee: Instant
Bean: Colombian
——————– Change Bean Type ———-
Set bean to Mixed
Bean Type is now Mixed
—————— Change Coffee Type ———-
Set coffee type to Instant
Type of coffee: Instant
In the above code, outputs when the first object foundation in the Hasche table the index is ‘ Bean’he’Coffee’di the value, after then transfers various members function change value, outputs again.
The method may have many parameters, now increases function makeCup() to the Coffee.pm module, the code is as follows:
sub makeCup {
my ($class, $cream, $sugar, $dope) = @_;
print “n================================== n”;
print “Making a cup n”;
print “Add cream n” if ($cream);
print “Add $sugar sugar cubesn” if ($sugar);
print “Making some really addictive coffee; -) n” if ($dope);
print “================================== n”;
}
This function may have three parameters, the different number, the value parameter has the different result, for example:
1 #! /usr/bin/perl
2 push (@INC, ‘pwd’);
3 use Coffee;
4 $cup = new Coffee;
5 #
6 # With no parameters
7 #
8 print “n Calling with no parameters: nâ
9 $cup->makeCup;
10 #
11 # With one parameter
12 #
13 print “n Calling with one parameter: n”;
14 $cup->makeCup (’1′);
15 #
16 # With two parameters
17 #
18 print “n Calling with two parameters: n”;
19 $cup->makeCup (1, ’2′);
20 #
21 # With all three parameters
22 #
23 print n Calling with three parameters: n”;
24 $cup->makeCup (’1′, 3, ’1′);
Its result output is as follows:
Calling with no parameters:
==================================
Making a cup
==================================
Calling with one parameter:
==================================
Making a cup
Add cream
==================================
Calling with two parameters:
==================================
Making a cup
Add cream
Add 2 sugar cubes
==================================
Calling with three parameters:
============
======================
Making a cup
Add cream
Add 3 sugar cubes
Making some really addictive coffee; -)
==================================
In this example, the function makeCup() parameter already may for the string of character also be possible to be the integer, the processing result is the same, you may also differentiate these two type data processing. To the parameter in processing, may establish the default value, may also act according to the actual input parameter value the integer to give different processing.
11th, subclass method heavy load
Inherits the advantage lies in may obtain the base class output the method function, but sometimes needs to obtain more concrete or a different function to base’s class method heavy load. Below joins method printType() in the Bean.pm kind, the code is as follows:
sub printType {
my $class = shift @_;
print “The type of Bean is $class-> {‘Bean’} n”;
}
Then renews its @EXPORT array to output:
@EXPORT = qw (setBeanType, printType);
Now transfers function printType(), three transfer method:
$cup->Coffee::printType();
$cup->printType();
$cup->Bean::printType();
The output distinction is as follows:
The type of Bean is Mixed
The type of Bean is Mixed
The type of Bean is Mixed
Is why same? Because in subclass defining function printType(), therefore transferred the base class method actually. If wants to enable the subclass to have its own printType() function, must perform in the Coffee.pm kind to define:
#
# This routine prints the type of $class-> {‘Coffee’}
#
sub printType {
my $class = shift @_;
print “The type of Coffee is $class-> {‘Coffee’} n”;
}
Then renews its @EXPORT array:
@EXPORT = qw (setImports, declareMain, closeMain, printType);
Now output has turned out:
The type of Coffee is Instant
The type of Coffee is Instant
The type of Bean is Mixed
Now only then, when has assigned Bean:: When only then transfers base’s class method, otherwise transfers the subclass directly the method.
If then did not know how the base class name should transfer the base class method? The method is uses false kind of reserved word SUPER:: . Uses the grammar in a kind of method for example: $this->SUPER:: function (¦ argument list…); , it will seek from the @ISA tabulation. A moment ago sentence used SUPER:: Replaces Bean:: May write is $cup->SUPER::printType(); , its result output is the same, is:
The type of Bean is Mixed
12th, Perl kind and object some annotations
The OOP biggest advantage is the code entrusts with heavy responsibility. OOP hides some complex codes with the data encapsulation, Perl Bao He the module provides the data encapsulation function through the my function, but Perl did not guarantee that the subclass will directly certainly not visit base’s class variable, this reduced the data encapsulation advantage truly, although this kind of movement will be may achieve, but actually will be the very bad programming style.
Attention:
1st, certainly must through the method visit class variable.
2nd, certainly do not from the module the direct visit class variable.
When compiles the package, should guarantee the method needs the condition has had or transmits through the parameter for it. In the package, should guarantee that only uses visit to global variable’s through the method transmission quotation to visit. Static state which or global data must use regarding the method, should define in the base class with local(), the subclass through transfers the base class to gain. Sometimes, the subclass possibly needs to change this kind of data, by now, the base class possibly did not know how to seek for the recent data, therefore, was best by now defines to this data quotation, the subclass and the base class changes this data through the quotation.
Finally, you will see the following way user and the kind:
use coffee::Bean;
This sentence’s meaning is “child directory seeks for Bean.pm in @INC the array all catalog Coffee”. If transfers to Bean.pm. the /Coffee table of contents, the example above will use this use sentence to work. Such advantage has orderliness organization’s class code. Moreover, following sentence:
use Another::Sub::Menu;
Means the following child directory tree:
./Another/Sub/Menu.pm