Chapter 13 Perl Object-Oriented Programming
I. Introduction to the module II, class three in Perl, create class four, constructor
Example Variable 5, Method 6, Method Output Seven, Method Call 8, Overloaded Nine, Destructor Dozens, Inherited Eleven, Overloaded Twelve, Perl Class and Object Some Note This chapter describes how to use Perl Object-Oriented Programming (OOP) features and how to build objects, including inheritance, method overload, and data packages. 1. Module Introduction Module is a PERL package (PERL). The objects in Perl are based on references to the data items in the package. (See Chapter X). See http://www.metronet.com's PerlMod and Perlobj. When performing object-oriented programming with other languages, first declare a class and create the object (instance) of this class, the behavior of all objects of a particular class is the same, and by the class method, you can define a new class or from the existing class inheritance. Create a class. People who are familiar with object-oriented programming can encounter many familiar terms. Perl has always been an object-oriented language. In Perl5, the syntax has changed slightly, and the use of objects is more standardized. The following three definitions are critical to understanding objects, classes, and methods in Perl. Class is a Perl package that includes classes that provide an object method. The method is a Perl subroutine, and the class name is its first parameter. The object is a reference to the data items in the class. Second, the classes in Perl emphasize that a PERL class is just a package. When you see the "class" in the Perl document, you will see it as a "package". Perl5's syntax can create classes, if you are familiar with C , you have already mastered most of the syntax. Different concepts with Perl4 are identified the basic class and inheritance class (subclass) with a double colon (: :). An important feature of object-oriented is inheritance. The inheritance characteristics in Perl are not exactly the other object-oriented language. It is only inherited, and you must use your own mechanism to achieve the inheritance of the data. Because each class is a package, it has its own namespace and its own symbolic associated array (see Chapter X), for details, each class, can you use your own independent symbolic name. Combined with the packet, you can use a single quotation mark (') operator to locate variables in the class, positioning forms of members such as $ Class' $ Member. In Perl5, you can use a double-quarantine alternative to a single quotation, such as: $ Class' is the same as $ Class :: $ MEMBER. Third, create a class. This section describes the necessary steps for creating a new class. The example below is to create a simple class called Cocoa, which is the necessary part of the source code for outputting a simple Java application. Don't worry, this example doesn't need you have Java knowledge, but you will not make you a Java expert, and its purpose is to tell the concept of creating classes. First, create a package file called Cocoa.pm (extension PM is the default extension of the package, meaning perl module). A module is a package, a package is a class. Before doing other things, join "1;" such a line, remember to keep "1;" for the last line when you increase other lines. This is the required condition of the Perl package, otherwise the package will not be processed by Perl. Below is the basic structure of the file.
Package cocoa; ## put "required" Statements in for all required, imported packages ## Just add code here # 1; # Terminate the package with the request 1;
Next, we add methods to the bag to make it a class. The first method to add is new (), which is a must be called when creating an object, and the new () method is the constructor of the object. Fourth, the constructor constructor is a subroutine of the class, which returns a reference related to the class name. A combination of class name and reference is called a "blessing", because the combination is established as bless (), its syntax is: bless yeference [, classname] Yereference is a reference to the object being "bless", classname It is optional, specifying the package name of the object acquisition method, which is the current package name. Creating a build function is a reference to the internal structure that has been combined with this class, such as: Sub New {MY $ this = {}; # create 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;
{} Creates a reference to a hash / value-paid hash table (ie, the associated array), and the return value is assigned to the LAN THIS. The function bless () Removes the reference, tells the object that it is cocoa, and finally returns the reference. The return value of the function is now pointing to this anonymous hash table. After returning from the new () function, the $ THIS is destroyed, but the call function saves the reference to the hash table, so the number of references to the hash table will not be zero, so that Perl saves the hash in memory. table. Creating an object can call as follows: $ CUP = New Cocoa; the following statement is an example of using the package to create an object:
1 #! / Usr / bin / perl2 push (@ INC, 'PWD'); 3 USE Cocoa; 4 $ Cup = New Cocoa;
The first line indicates the location of the Perl interpreter, in the second line, add the current directory to the path search list @inc for the package for the package. You can also create your module in different directories and point out the absolute path. For example, if the / home / test / scripts / creation package, the second line should be as follows: Push (@inc, "/ home / test / scripts); in the third line, include the upper package cocoa.pm for The feature required in the script. The USE statement tells Perl to look for file cocoa.pm in the @inc path and contain the parsed source file copy. The USE statement is the class must be used. The fourth line calls the new function to create an object. This is the beauty of Perl, and it is also an easy confusion, it is also a powerful place. There are many ways to create objects, you can write: $ cup = cocoa-> new (); if you are a C programmer, you can use a double colon to use the New () function in the COCOA package, such as: $ Cup = Cocoa :: new (); more code can be added to the constructor, as in Cocoa.pm, you can output a simple declaration when you create each object, and you can also initialize the variable or set an array or pointer with a constructor. note:
1. Be sure to initialize the variable in the constructor; 2, must use the My function to create variables in the method; 3, do not use local in the method, unless you really want to pass the variable to other subroutines; 4, must not Use global variables in class modules.
The Cocoa constructor declared as follows:
Sub new {MY $ this = {}; print "/ n / * / n ** create by cocoa.pm / n ** use at own risk"; print "/ n ** Did this code even get pass the Javac Compiler ? "; Print" / n ** / / / / / / /}); Return $ this;} You can also simply call in the package or other functions outside the package to do more initialization work, such as:
Sub new {MY $ this = {} Bless $ this; $ this-> doinitialization (); return $ this;}
When you create a class, it should be allowed to be inherited, you should use the class name as the first parameter to call the New function, then the new function is like the following statement:
Sub new {MY $ Class = Shift; # get the request class name my $ this = {}; Bless $ this $ class # use class name to bless $ this-> doinitialization (); return $ this;}
This method allows users to call one of three ways:
Cocoa :: new () cocoa-> new () New Cocoa can multiple times a reference object, however, the new will be removed by Bless's class, and the C and PASCAL programmers, This is like a piece of memory assigned to the assigned, and then assigns the same point to another memory without releasing the previous memory. In short, a Perl object can only belong to a class every moment. What is the real difference between objects and references? Perl objects are blesces to be a class. Otherwise, if referenced by Bless, it will belong to a class, but also become an object. Object know which class you belong to, the reference is not any class. Example variables are called instance variables as the parameters of the new () function of the constructor. Example variables are used to initialize each instance of the object, for example, can use a new () function to give each instance of each instance of the object. Instance variables can be saved with anonymous hash table or an anonymous array. The code with the hash table is as follows:
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 saved with 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, $ TYI
}
When constructing an object, you can pass parameters as follows: $ mug = Cocoa :: new ('name' => 'top', 'x' => 10, 'y' => 20); operator => and comma operating suit The same, but => is well readable. The access method is as follows: Print "name = $ mug -> {'name'} / n"; print "x} / $ mug -> {'x'} / n"; print "y = $ mug -> {'y' } / n "; 5. The method of the method Perl class is just a Perl subroutine, that is, the usual member function. Perl's method definition does not provide any special syntax, but the first parameter of the specified method is an object or its referenced package. There are two ways: static methods and false methods. The first parameter of the static method is class name, the first parameter of the virtual method is the reference. Methods to deal with the first parameter determine whether it is still still or virtual. Static methods generally ignore the first parameters because they already know which class, the constructor is a static method. The virtual method usually first puts the first parameter Shift to the variable Self or THIS, and then uses the value to be used for normal reference. Such as: 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, the output of the method If you want to quote the Cocoa.pm package now, you will get a compilation error saying that the method is not found because Cocoa.pm has not been output yet. The output method requires an Exporter module, plus the following two lines in the beginning of the package: Require exporter; @ISA = QW (Exporter); these two lines contain the exporter.pm module and add the Exporter class name to the @ISA array for findings . Next, you can list your own class method in the @Export array. For example, if you want to output methods, Closemain and Declaremain, the statement is as follows: @Export = QW (DeclareMain, Closemain); the inheritance of the Perl class is implemented through the @ISA array. The @isa array does not need to be defined in any package, however, once it is defined, Perl regards it as a special array of directory names. It is similar to the @Inc array, @ INC is a search path containing files. The @ISA array contains a class (package) name, when a method is not found in the current package, go to the package in @ISA to find it. @ISA also contains the base class name inherited by the current class. All methods in the class must belong to the base class defined by the same class or an @isa array. If a method is not found in the @ISA array, Perl is looking for in the AutoLoad () subroutine, which is defined in the current packet. If you use the AutoLoad subroutine, you must call the AutoLoad.pm package with the USE AutoLoad; statement. The AutoLoad subroutine tries to load the call from the installed Perl library. If AutoLoad also fails, Perl will do the last attempt to the Universal class. If it is still failed, Perl generates an error on the unable to resolve functions. Seven, the method of calling to call an object has two methods, one is the reference (virtual method) of the object, one is to use the class name (static method). Of course, this method must have been output. Now add some methods to the Cocoa class, 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";} # ## routine declares the main function in a java script # SUB DECLAREMAIN {MY $ Class = Shift @_; MY ($ Name, $ EXTENDS, $ IMPLEMENTS) = @_; print "/ n public class $ name"; if ($ extend "{print" Extends ". $ Extend;}}}} {Print "import"} "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 ** create 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 class, below is the script code for creating a Java Applet source skeleton:
#! / usr / bin / Perluse Cocoa; $ CUP = New Cocoa; $ CUP-> SetimPorts ('Java.Io.inputStream', 'java.net. *'); $ Cup-> Declaremain ("msg", " Java.applet.applet "," runnable "); $ CUP-> Closemain ();
This script created a Java Applet called MSG, which extension has a java.applet.applet.applet.applet.Anable, where the last three rows can be written as follows:
Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); Cocoa :: Declaremain ($ CUP, "MSG", "Java.applet.applet", "runnable"); Cocoa :: Closemain ($ CUP);
The results of its operation are as follows:
/ *** Created by cocoa.pm ** use at own risk * / import java.io.inputstream; import java.net. *; Public class msg extends java.applet.applet imports runnable {} Note: If you use-> Operator call (also called indirect call), parameters must be enclosed in parentheses, such as $ cup-> setimports ('java.io.inputstream', 'java.net. *'); And double colon call such as: Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); can also remove the brackets: Cocoa :: Setimports $ CUP, 'Java.io.inputStream', 'Java.net. * '; Eight, the overload sometimes needs to specify which class of methods, such as two different classes have the same name method. Assuming that class espresso and qava define how to use :: operator Specify use of QAVA: $ Mess = Qava :: Grind ("Whole", "Lotta", "Bags"); QAVA :: Grind ($ Mess, "whole", "Lotta", "Bags"); which class can be selected according to the operation of the program, this can be implemented by using symbol reference: $ gethod = $ local? "Qava :: ": Espresso ::"; $ Cup -> {$ method} Grind (@args); Nine, the destructor Perl tracks the number of links to the object, when the last application of an object is released to the memory pool, the object is Automatic destruction. The sector of the object occurs after the code is stopped, the script will end. For global variables, the designer has occurred after the last line of code is running. If you want to get control before the object is released, you can define the destroy () method. DESTROY () is called before the object will be released so that you can do some cleanup work. The DESTROY () function does not automatically call other DESTROY () functions, and Perl does not do built-in destructure work. If the constructor is multiple times, DESTROY () may need to call other class DESTROY () functions. When an object is released, all objects included are automatically released and destroyed. In general, it is not necessary to define the destroy () function, if needed, the form is as follows:
Sub destroy {## add code here. #}
Because of a variety of purposes, Perl uses simple, reference-based garbage collection system. The number of references to any object must be greater than zero, otherwise the memory of the object is released. When the program exits, a thorough lookup of Perl and destroys functions for garbage collection, and everything in the process is simply deleted. In the Unix class system, this is excessive, but this is indeed necessary in an in-room or multi-threaded environment. X. Inheritability methods are inherited by @ISA array, and the inheritance of variables must be clearly set. The following example creates two class bean.pm and coffee.pm, where Coffee.PM inherits some of the features of bean.pm. This example demonstrates how to inherit instance variables from the base class (or super class), which is called the constructor of the base class and adds its own instance variable to the new object. Bean.pm code is as follows:
Package bean; @isa = qw (exporter); @ @ e = qw (setBeantype); Sub New {MY $ TYPE = Shift; My $ this = {}; $ this -> {'bean'} = 'colorbian '; $ THIS; RETURN $ THIS;} ## this subroutine set the class namesub setBeantype {MY ($ Class, $ name) @__; $ class -> {' bean '} = $ name; print "Set Bean to $ Name / N"; 1;
In this class, set an anonymous hash table with $ this variable, set the 'bean' type to 'Colombian'. Method setBeantype () is used to change the 'bean' type, which uses the $ Class reference to get access to the object hash table. 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 item11 # 12 SETCOFEETYPE {13 My ($ Class, $ Name) = @_; 14 $ Class -> {'coffee'} = $ name; 15 print "set coffee type to $ name / n "; 16} 17 # 18 # Constructor19 # 20 Sub new {21 my $ type = shift; 22 my $ this = bean-> new (); #####
The second line of the Require bean; statement contains the bean.pm file and all related functions, and method setCoffeeType () is used to set the value of the local variable $ Class -> {'Coffee'}. In the constructor new (), $ this points to the pointer of the anonymous hash table returned by bean.pm, not in the local creation, the following two statements are created with the bean.pm constructor, respectively. The hash table is not related to the situation and inheritance: My $ this = {}; # 不 继 m $ this = $ THESUPERCLASS-> new (); # Inherit the following code demonstrate how to call inheritance:
1 #! / Usr / bin / perl2 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 ------------------------ / N " ; 9 $ CUP-> setBeantype ('Mixed'); 10 Print "Bean Type is now $ CUP -> {'bean'} / n"; 11 print "/ n ------------ ---------- / N "; 12 $ CUP-> SetCoffeetyPE ('Instant'); 13 Print" Type of Coffee: $ cup -> {'coffee' } / n "; the result of this code is as follows:
-------------------- Initial Values ------------ Coffee: Instantbean: Colombian ----------- --------- Change Bean Type --------- set bean to mixedbean type is now mixed ---------------- Change coffee TYPE ---------- Set coffee type to instanttype of coffee: instant
In the above code, the index of the index in the hasxiety in the hasxiety is the value of 'ben' and 'coffee' at the time of the object creation, and then the member function changes the value after the value is then output. Methods can have multiple parameters, and now add functions 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 cubes / n "if ($ sugar) PRINT "MAKING SOME Real" ================================================================ ====== / n ";}
This function can have three parameters, different numbers, value parameters produce different results, for example: 1 #! / Usr / bin / perl2 push (@ INC, 'PWD'); 3 Use coffee; 4 $ CUP = New Coffee; 5 # 6 # with no parameters7 # 8 print "/ n calling with no parameters: / n"; 9 $ CUP-> makecup; 10 # 11 # with one parameter12 # 13 print "/ n calling with one parameter: / n" 14 $ CUP-> Makecup ('1'); 15 # 16 # with Two Parameters17 # 18 Print "/ N Calling with Two Parameters: / N"; 19 $ CUP-> Makecup (1, '2'); 20 # 21 # with all three parameters22 # 23 print "/ n Calling with three parameters: / n"; 24 $ CUP-> Makecup ('1', 3, '1');
The result is output as follows:
Calling with no parameters: ================================== ================= ========================== caverling with one parameter: ================================================================================================================================================================================================================================ =============== Making a cupadd create =============================== === Calling with two parameters: =========================================== Making a cupadd created 2 sugar cubes = ================================= caverling with three parameters: ====================== ====================== Making a cupadd create some really addictive coffee; -) ============== ====================
In this example, the parameters of the function makecup () can be used for both a string, and the processing result is the same, and you can also divide these two types of data processing. In the process of parameters, the default value can be set, or different processing can also be given according to the number of actual input parameter values. XI, the benefit of the overload inheritance of the sub-class method is the function of obtaining the method of the base class output, and sometimes it needs to be overloaded to the base class to obtain more specific or different functions. The following is in the bean.pm class to join the method printepe (), the code is as follows: Sub printType {MY $ Class = Shift @_; print "The Type of Bean IS $ Class -> {'bean'} / n";}
Then update its @export array to output: @export = QW (setBeantype, prinTType); now call the function prinTtype (), there are three call methods:
$ Cup-> Coffee :: PrintType (); $ CUP-> PrintType (); $ CUP-> bean :: prinTtype ();
The output is as follows:
The Type of Bean Is Mixedthe Type of Bean Is Mixedthe Type of Bean IS Mixed
Why is it the same? Since the function prinTType () is not defined in the subclass, the method in the base class is actually called. If you want to make the subclasses have their own PrintType () function, you must define in the Coffee.PM class:
## rtine prints The Type of $ Class -> {'coffee'} # Sub PrintType {MY $ Class = Shift @_; print "The Type of coffee is $ class -> {'coffee'} / n";}
Then update its @Export arrays: @Export = QW (Setimports, Declaremain, Closemain, PrintType); Now output results become:
The Type of Coffee Is Instantthe Type of Coffee Is Instantthe Type of Bean IS Mixed
Now there is only a method of calling the subclass directly when it is given for the bean ::. So if you don't know how the base class name calls a base class method? The method is to use a pseudo-class reserved word Super ::. Use grammar in the class method such as $ this-> super :: function (... argument list ...); it will be found in the @isa list. Just now: Replacing Bean :: CUP-> Super :: printtype ();:::
The Type of Bean is Mixed
Twelve, the biggest advantage of some comments OOP of Perl class and object is the code reuse. OOP with data package hides some complex code, Perl package and module provide data package function via the MY function, but Perl does not guarantee that the subclass will not directly access the variables of the base class, which does not reduce the benefits of data packaging, Although this action can be done, it is a very bad programming style. note:
1. Be sure to access the class variables by way. 2, must not access the class variables directly from the outside of the module.
When writing a package, you should guarantee that the conditions needed to have or pass through parameters to it. Inside the package, it should be ensured that access to global variables is only accessed by reference to the reference. For static or global data to use, you should define locations in the base class, the subclays are obtained by calling the base class. Sometimes, the subclass may need to change this data. At this time, the base class may not know how to find new data, so it is best to define the reference, subclasses, and base classes to change by reference. This data. Finally, you will see the following objects and classes: Use coffee :: bean; the meaning of this sentence is "Coffee subdirectory of all directories in the @Inc array". If you move bean.pm to the ./coffee directory, the above example will work with this USE statement. Such benefits are code for organizing classes. Another example, the following statement: Use annother :: sub :: menu; means that the parameter variable is called the new () function of the constructor as the next subdirectory tree: ./another/Sub/Menu.pm instance variable is called instance variables. Example variables are used to initialize each instance of the object, for example, can use a new () function to give each instance of each instance of the object. Instance variables can be saved with anonymous hash table or an anonymous array. The code with the hash table is as follows:
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 saved with 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, $ TYI
}
When constructing an object, you can pass parameters as follows: $ mug = Cocoa :: new ('name' => 'top', 'x' => 10, 'y' => 20); operator => and comma operating suit The same, but => is well readable. The access method is as follows: Print "name = $ mug -> {'name'} / n"; print "x} / $ mug -> {'x'} / n"; print "y = $ mug -> {'y' } / n "; 5. The method of the method Perl class is just a Perl subroutine, that is, the usual member function. Perl's method definition does not provide any special syntax, but the first parameter of the specified method is an object or its referenced package. There are two ways: static methods and false methods. The first parameter of the static method is class name, the first parameter of the virtual method is the reference. Methods to deal with the first parameter determine whether it is still still or virtual. Static methods generally ignore the first parameters because they already know which class, the constructor is a static method. The virtual method usually first puts the first parameter Shift to the variable Self or THIS, and then uses the value to be used for normal reference. Such as: 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, the output of the method If you want to quote the Cocoa.pm package now, you will get a compilation error saying that the method is not found because Cocoa.pm has not been output yet. The output method requires an Exporter module, plus the following two lines in the beginning of the package: Require exporter; @ISA = QW (Exporter); these two lines contain the exporter.pm module and add the Exporter class name to the @ISA array for findings . Next, you can list your own class method in the @Export array. For example, if you want to output methods, Closemain and Declaremain, the statement is as follows: @Export = QW (DeclareMain, Closemain); the inheritance of the Perl class is implemented through the @ISA array. The @isa array does not need to be defined in any package, however, once it is defined, Perl regards it as a special array of directory names. It is similar to the @Inc array, @ INC is a search path containing files. The @ISA array contains a class (package) name, when a method is not found in the current package, go to the package in @ISA to find it. @ISA also contains the base class name inherited by the current class. All methods in the class must belong to the base class defined by the same class or an @isa array. If a method is not found in the @ISA array, Perl is looking for in the AutoLoad () subroutine, which is defined in the current packet. If you use the AutoLoad subroutine, you must call the AutoLoad.pm package with the USE AutoLoad; statement. The AutoLoad subroutine tries to load the call from the installed Perl library. If AutoLoad also fails, Perl will do the last attempt to the Universal class. If it is still failed, Perl generates an error on the unable to resolve functions. Seven, the method of calling to call an object has two methods, one is the reference (virtual method) of the object, one is to use the class name (static method). Of course, this method must have been output. Now add some methods to the Cocoa class, 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";} # ## routine declares the main function in a java script # SUB DECLAREMAIN {MY $ Class = Shift @_; MY ($ Name, $ EXTENDS, $ IMPLEMENTS) = @_; print "/ n public class $ name"; if ($ extend "{print" Extends ". $ Extend;}}}} {Print "import"} "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 ** create 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 class, below is the script code for creating a Java Applet source skeleton:
#! / usr / bin / Perluse Cocoa; $ CUP = New Cocoa; $ CUP-> SetimPorts ('Java.Io.inputStream', 'java.net. *'); $ Cup-> Declaremain ("msg", " Java.applet.applet "," runnable "); $ CUP-> Closemain ();
This script created a Java Applet called MSG, which extension has a java.applet.applet.applet.applet.Anable, where the last three rows can be written as follows:
Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); Cocoa :: Declaremain ($ CUP, "MSG", "Java.applet.applet", "runnable"); Cocoa :: Closemain ($ CUP);
The results of its operation are as follows:
/ *** Created by cocoa.pm ** use at own risk * / import java.io.inputstream; import java.net. *; Public class msg extends java.applet.applet imports runnable {} Note: If you use-> Operator call (also called indirect call), parameters must be enclosed in parentheses, such as $ cup-> setimports ('java.io.inputstream', 'java.net. *'); And double colon call such as: Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); can also remove the brackets: Cocoa :: Setimports $ CUP, 'Java.io.inputStream', 'Java.net. * '; Eight, the overload sometimes needs to specify which class of methods, such as two different classes have the same name method. Assuming that class espresso and qava define how to use :: operator Specify use of QAVA: $ Mess = Qava :: Grind ("Whole", "Lotta", "Bags"); QAVA :: Grind ($ Mess, "whole", "Lotta", "Bags"); which class can be selected according to the operation of the program, this can be implemented by using symbol reference: $ gethod = $ local? "Qava :: ": Espresso ::"; $ Cup -> {$ method} Grind (@args); Nine, the destructor Perl tracks the number of links to the object, when the last application of an object is released to the memory pool, the object is Automatic destruction. The sector of the object occurs after the code is stopped, the script will end. For global variables, the designer has occurred after the last line of code is running. If you want to get control before the object is released, you can define the destroy () method. DESTROY () is called before the object will be released so that you can do some cleanup work. The DESTROY () function does not automatically call other DESTROY () functions, and Perl does not do built-in destructure work. If the constructor is multiple times, DESTROY () may need to call other class DESTROY () functions. When an object is released, all objects included are automatically released and destroyed. In general, it is not necessary to define the destroy () function, if needed, the form is as follows:
Sub destroy {## add code here. #}
Because of a variety of purposes, Perl uses simple, reference-based garbage collection system. The number of references to any object must be greater than zero, otherwise the memory of the object is released. When the program exits, a thorough lookup of Perl and destroys functions for garbage collection, and everything in the process is simply deleted. In the Unix class system, this is excessive, but this is indeed necessary in an in-room or multi-threaded environment. X. Inheritability methods are inherited by @ISA array, and the inheritance of variables must be clearly set. The following example creates two class bean.pm and coffee.pm, where Coffee.PM inherits some of the features of bean.pm. This example demonstrates how to inherit instance variables from the base class (or super class), which is called the constructor of the base class and adds its own instance variable to the new object. Bean.pm code is as follows:
Package bean; @isa = qw (exporter); @ @ e = qw (setBeantype); Sub New {MY $ TYPE = Shift; My $ this = {}; $ this -> {'bean'} = 'colorbian '; $ THIS; RETURN $ THIS;} ## this subroutine set the class namesub setBeantype {MY ($ Class, $ name) @__; $ class -> {' bean '} = $ name; print "Set Bean to $ Name / N"; 1;
In this class, set an anonymous hash table with $ this variable, set the 'bean' type to 'Colombian'. Method setBeantype () is used to change the 'bean' type, which uses the $ Class reference to get access to the object hash table. 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 item11 # 12 SETCOFEETYPE {13 My ($ Class, $ Name) = @_; 14 $ Class -> {'coffee'} = $ name; 15 print "set coffee type to $ name / n "; 16} 17 # 18 # Constructor19 # 20 Sub new {21 my $ type = shift; 22 my $ this = bean-> new (); #####
The second line of the Require bean; statement contains the bean.pm file and all related functions, and method setCoffeeType () is used to set the value of the local variable $ Class -> {'Coffee'}. In the constructor new (), $ this points to the pointer of the anonymous hash table returned by bean.pm, not in the local creation, the following two statements are created with the bean.pm constructor, respectively. The hash table is not related to the situation and inheritance: My $ this = {}; # 不 继 m $ this = $ THESUPERCLASS-> new (); # Inherit the following code demonstrate how to call inheritance:
1 #! / Usr / bin / perl2 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 ------------------------ / N " ; 9 $ CUP-> setBeantype ('Mixed'); 10 Print "Bean Type is now $ CUP -> {'bean'} / n"; 11 print "/ n ------------ ---------- / N "; 12 $ CUP-> SetCoffeetyPE ('Instant'); 13 Print" Type of Coffee: $ cup -> {'coffee' } / n "; the result of this code is as follows:
-------------------- Initial Values ------------ Coffee: Instantbean: Colombian ----------- --------- Change Bean Type --------- set bean to mixedbean type is now mixed ---------------- Change coffee TYPE ---------- Set coffee type to instanttype of coffee: instant
In the above code, the index of the index in the hasxiety in the hasxiety is the value of 'ben' and 'coffee' at the time of the object creation, and then the member function changes the value after the value is then output. Methods can have multiple parameters, and now add functions 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 cubes / n "if ($ sugar) PRINT "MAKING SOME Real" ================================================================ ====== / n ";}
This function can have three parameters, different numbers, value parameters produce different results, for example: 1 #! / Usr / bin / perl2 push (@ INC, 'PWD'); 3 Use coffee; 4 $ CUP = New Coffee; 5 # 6 # with no parameters7 # 8 print "/ n calling with no parameters: / n"; 9 $ CUP-> makecup; 10 # 11 # with one parameter12 # 13 print "/ n calling with one parameter: / n" 14 $ CUP-> Makecup ('1'); 15 # 16 # with Two Parameters17 # 18 Print "/ N Calling with Two Parameters: / N"; 19 $ CUP-> Makecup (1, '2'); 20 # 21 # with all three parameters22 # 23 print "/ n Calling with three parameters: / n"; 24 $ CUP-> Makecup ('1', 3, '1');
The result is output as follows:
Calling with no parameters: ================================== ================= ========================== caverling with one parameter: ================================================================================================================================================================================================================================ =============== Making a cupadd create =============================== === Calling with two parameters: =========================================== Making a cupadd created 2 sugar cubes = ================================= caverling with three parameters: ====================== ====================== Making a cupadd create some really addictive coffee; -) ============== ====================
In this example, the parameters of the function makecup () can be used for both a string, and the processing result is the same, and you can also divide these two types of data processing. In the process of parameters, the default value can be set, or different processing can also be given according to the number of actual input parameter values. XI, the benefit of the overload inheritance of the sub-class method is the function of obtaining the method of the base class output, and sometimes it needs to be overloaded to the base class to obtain more specific or different functions. The following is in the bean.pm class to join the method printepe (), the code is as follows: Sub printType {MY $ Class = Shift @_; print "The Type of Bean IS $ Class -> {'bean'} / n";}
Then update its @export array to output: @export = QW (setBeantype, prinTType); now call the function prinTtype (), there are three call methods:
$ Cup-> Coffee :: PrintType (); $ CUP-> PrintType (); $ CUP-> bean :: prinTtype ();
The output is as follows:
The Type of Bean Is Mixedthe Type of Bean Is Mixedthe Type of Bean IS Mixed
Why is it the same? Since the function prinTType () is not defined in the subclass, the method in the base class is actually called. If you want to make the subclasses have their own PrintType () function, you must define in the Coffee.PM class:
## rtine prints The Type of $ Class -> {'coffee'} # Sub PrintType {MY $ Class = Shift @_; print "The Type of coffee is $ class -> {'coffee'} / n";}
Then update its @Export arrays: @Export = QW (Setimports, Declaremain, Closemain, PrintType); Now output results become:
The Type of Coffee Is Instantthe Type of Coffee Is Instantthe Type of Bean IS Mixed
Now there is only a method of calling the subclass directly when it is given for the bean ::. So if you don't know how the base class name calls a base class method? The method is to use a pseudo-class reserved word Super ::. Use grammar in the class method such as $ this-> super :: function (... argument list ...); it will be found in the @isa list. Just now: Replacing Bean :: CUP-> Super :: printtype ();:::
The Type of Bean is Mixed
Twelve, the biggest advantage of some comments OOP of Perl class and object is the code reuse. OOP with data package hides some complex code, Perl package and module provide data package function via the MY function, but Perl does not guarantee that the subclass will not directly access the variables of the base class, which does not reduce the benefits of data packaging, Although this action can be done, it is a very bad programming style. note:
1. Be sure to access the class variables by way. 2, must not access the class variables directly from the outside of the module.
When writing a package, you should guarantee that the conditions needed to have or pass through parameters to it. Inside the package, it should be ensured that access to global variables is only accessed by reference to the reference. For static or global data to use, you should define locations in the base class, the subclays are obtained by calling the base class. Sometimes, the subclass may need to change this data. At this time, the base class may not know how to find new data, so it is best to define the reference, subclasses, and base classes to change by reference. This data. Finally, you will see the following objects and classes: Use coffee :: bean; the meaning of this sentence is "Coffee subdirectory of all directories in the @Inc array". If you move bean.pm to the ./coffee directory, the above example will work with this USE statement. Such benefits are code for organizing classes. Another example, the following statement: Use another :: sub :: menu; means as the next list of directory: ./another/sub/Menu.pm
Example Variable 5, Method 6, Method Output Seven, Method Call 8, Overloaded Nine, Destructor Dozens, Inherited Eleven, Overloaded Twelve, Perl Class and Object Some Note This chapter describes how to use Perl Object-Oriented Programming (OOP) features and how to build objects, including inheritance, method overload, and data packages. 1. Module Introduction Module is a PERL package (PERL). The objects in Perl are based on references to the data items in the package. (See Chapter X). See http://www.metronet.com's PerlMod and Perlobj. When performing object-oriented programming with other languages, first declare a class and create the object (instance) of this class, the behavior of all objects of a particular class is the same, and by the class method, you can define a new class or from the existing class inheritance. Create a class. People who are familiar with object-oriented programming can encounter many familiar terms. Perl has always been an object-oriented language. In Perl5, the syntax has changed slightly, and the use of objects is more standardized. The following three definitions are critical to understanding objects, classes, and methods in Perl. Class is a Perl package that includes classes that provide an object method. The method is a Perl subroutine, and the class name is its first parameter. The object is a reference to the data items in the class. Second, the classes in Perl emphasize that a PERL class is just a package. When you see the "class" in the Perl document, you will see it as a "package". Perl5's syntax can create classes, if you are familiar with C , you have already mastered most of the syntax. Different concepts with Perl4 are identified the basic class and inheritance class (subclass) with a double colon (: :). An important feature of object-oriented is inheritance. The inheritance characteristics in Perl are not exactly the other object-oriented language. It is only inherited, and you must use your own mechanism to achieve the inheritance of the data. Because each class is a package, it has its own namespace and its own symbolic associated array (see Chapter X), for details, each class, can you use your own independent symbolic name. Combined with the packet, you can use a single quotation mark (') operator to locate variables in the class, positioning forms of members such as $ Class' $ Member. In Perl5, you can use a double-quarantine alternative to a single quotation, such as: $ Class' is the same as $ Class :: $ MEMBER. Third, create a class. This section describes the necessary steps for creating a new class. The example below is to create a simple class called Cocoa, which is the necessary part of the source code for outputting a simple Java application. Don't worry, this example doesn't need you have Java knowledge, but you will not make you a Java expert, and its purpose is to tell the concept of creating classes. First, create a package file called Cocoa.pm (extension PM is the default extension of the package, meaning perl module). A module is a package, a package is a class. Before doing other things, join "1;" such a line, remember to keep "1;" for the last line when you increase other lines. This is the required condition of the Perl package, otherwise the package will not be processed by Perl. Below is the basic structure of the file. Package cocoa; ## put "required" Statements in for all required, imported packages ## Just add code here # 1; # Terminate the package with the request 1;
Next, we add methods to the bag to make it a class. The first method to add is new (), which is a must be called when creating an object, and the new () method is the constructor of the object. Fourth, the constructor constructor is a subroutine of the class, which returns a reference related to the class name. A combination of class name and reference is called a "blessing", because the combination is established as bless (), its syntax is: bless yeference [, classname] Yereference is a reference to the object being "bless", classname It is optional, specifying the package name of the object acquisition method, which is the current package name. Creating a build function is a reference to the internal structure that has been combined with this class, such as: Sub New {MY $ this = {}; # create 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;
{} Creates a reference to a hash / value-paid hash table (ie, the associated array), and the return value is assigned to the LAN THIS. The function bless () Removes the reference, tells the object that it is cocoa, and finally returns the reference. The return value of the function is now pointing to this anonymous hash table. After returning from the new () function, the $ THIS is destroyed, but the call function saves the reference to the hash table, so the number of references to the hash table will not be zero, so that Perl saves the hash in memory. table. Creating an object can call as follows: $ CUP = New Cocoa; the following statement is an example of using the package to create an object:
1 #! / Usr / bin / perl2 push (@ INC, 'PWD'); 3 USE Cocoa; 4 $ Cup = New Cocoa;
The first line indicates the location of the Perl interpreter, in the second line, add the current directory to the path search list @inc for the package for the package. You can also create your module in different directories and point out the absolute path. For example, if the / home / test / scripts / creation package, the second line should be as follows: Push (@inc, "/ home / test / scripts); in the third line, include the upper package cocoa.pm for The feature required in the script. The USE statement tells Perl to look for file cocoa.pm in the @inc path and contain the parsed source file copy. The USE statement is the class must be used. The fourth line calls the new function to create an object. This is the beauty of Perl, and it is also an easy confusion, it is also a powerful place. There are many ways to create objects, you can write: $ cup = cocoa-> new (); if you are a C programmer, you can use a double colon to use the New () function in the COCOA package, such as: $ Cup = Cocoa :: new (); more code can be added to the constructor, as in Cocoa.pm, you can output a simple declaration when you create each object, and you can also initialize the variable or set an array or pointer with a constructor. note:
1. Be sure to initialize the variable in the constructor; 2, must use the My function to create variables in the method; 3, do not use local in the method, unless you really want to pass the variable to other subroutines; 4, must not Use global variables in class modules.
The Cocoa constructor declared as follows:
Sub new {MY $ this = {}; print "/ n / * / n ** create by cocoa.pm / n ** use at own risk"; print "/ n ** Did this code even get pass the Javac Compiler ? "; Print" / n ** / / / / / / /}); Return $ this;} You can also simply call in the package or other functions outside the package to do more initialization work, such as:
Sub new {MY $ this = {} Bless $ this; $ this-> doinitialization (); return $ this;}
When you create a class, it should be allowed to be inherited, you should use the class name as the first parameter to call the New function, then the new function is like the following statement:
Sub new {MY $ Class = Shift; # get the request class name my $ this = {}; Bless $ this $ class # use class name to bless $ this-> doinitialization (); return $ this;}
This method allows users to call one of three ways:
Cocoa :: new () cocoa-> new () New Cocoa can multiple times a reference object, however, the new will be removed by Bless's class, and the C and PASCAL programmers, This is like a piece of memory assigned to the assigned, and then assigns the same point to another memory without releasing the previous memory. In short, a Perl object can only belong to a class every moment. What is the real difference between objects and references? Perl objects are blesces to be a class. Otherwise, if referenced by Bless, it will belong to a class, but also become an object. Object know which class you belong to, the reference is not any class. Example variables are called instance variables as the parameters of the new () function of the constructor. Example variables are used to initialize each instance of the object, for example, can use a new () function to give each instance of each instance of the object. Instance variables can be saved with anonymous hash table or an anonymous array. The code with the hash table is as follows:
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 saved with 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, $ TYI
}
When constructing an object, you can pass parameters as follows: $ mug = Cocoa :: new ('name' => 'top', 'x' => 10, 'y' => 20); operator => and comma operating suit The same, but => is well readable. The access method is as follows: Print "name = $ mug -> {'name'} / n"; print "x} / $ mug -> {'x'} / n"; print "y = $ mug -> {'y' } / n "; 5. The method of the method Perl class is just a Perl subroutine, that is, the usual member function. Perl's method definition does not provide any special syntax, but the first parameter of the specified method is an object or its referenced package. There are two ways: static methods and false methods. The first parameter of the static method is class name, the first parameter of the virtual method is the reference. Methods to deal with the first parameter determine whether it is still still or virtual. Static methods generally ignore the first parameters because they already know which class, the constructor is a static method. The virtual method usually first puts the first parameter Shift to the variable Self or THIS, and then uses the value to be used for normal reference. Such as: 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, the output of the method If you want to quote the Cocoa.pm package now, you will get a compilation error saying that the method is not found because Cocoa.pm has not been output yet. The output method requires an Exporter module, plus the following two lines in the beginning of the package: Require exporter; @ISA = QW (Exporter); these two lines contain the exporter.pm module and add the Exporter class name to the @ISA array for findings . Next, you can list your own class method in the @Export array. For example, if you want to output methods, Closemain and Declaremain, the statement is as follows: @Export = QW (DeclareMain, Closemain); the inheritance of the Perl class is implemented through the @ISA array. The @isa array does not need to be defined in any package, however, once it is defined, Perl regards it as a special array of directory names. It is similar to the @Inc array, @ INC is a search path containing files. The @ISA array contains a class (package) name, when a method is not found in the current package, go to the package in @ISA to find it. @ISA also contains the base class name inherited by the current class. All methods in the class must belong to the base class defined by the same class or an @isa array. If a method is not found in the @ISA array, Perl is looking for in the AutoLoad () subroutine, which is defined in the current packet. If you use the AutoLoad subroutine, you must call the AutoLoad.pm package with the USE AutoLoad; statement. The AutoLoad subroutine tries to load the call from the installed Perl library. If AutoLoad also fails, Perl will do the last attempt to the Universal class. If it is still failed, Perl generates an error on the unable to resolve functions. Seven, the method of calling to call an object has two methods, one is the reference (virtual method) of the object, one is to use the class name (static method). Of course, this method must have been output. Now add some methods to the Cocoa class, 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";} # ## routine declares the main function in a java script # SUB DECLAREMAIN {MY $ Class = Shift @_; MY ($ Name, $ EXTENDS, $ IMPLEMENTS) = @_; print "/ n public class $ name"; if ($ extend "{print" Extends ". $ Extend;}}}} {Print "import"} "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 ** create 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 class, below is the script code for creating a Java Applet source skeleton:
#! / usr / bin / Perluse Cocoa; $ CUP = New Cocoa; $ CUP-> SetimPorts ('Java.Io.inputStream', 'java.net. *'); $ Cup-> Declaremain ("msg", " Java.applet.applet "," runnable "); $ CUP-> Closemain ();
This script created a Java Applet called MSG, which extension has a java.applet.applet.applet.applet.Anable, where the last three rows can be written as follows:
Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); Cocoa :: Declaremain ($ CUP, "MSG", "Java.applet.applet", "runnable"); Cocoa :: Closemain ($ CUP);
The results of its operation are as follows:
/ *** Created by cocoa.pm ** use at own risk * / import java.io.inputstream; import java.net. *; Public class msg extends java.applet.applet imports runnable {} Note: If you use-> Operator call (also called indirect call), parameters must be enclosed in parentheses, such as $ cup-> setimports ('java.io.inputstream', 'java.net. *'); And double colon call such as: Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); can also remove the brackets: Cocoa :: Setimports $ CUP, 'Java.io.inputStream', 'Java.net. * '; Eight, the overload sometimes needs to specify which class of methods, such as two different classes have the same name method. Assuming that class espresso and qava define how to use :: operator Specify use of QAVA: $ Mess = Qava :: Grind ("Whole", "Lotta", "Bags"); QAVA :: Grind ($ Mess, "whole", "Lotta", "Bags"); which class can be selected according to the operation of the program, this can be implemented by using symbol reference: $ gethod = $ local? "Qava :: ": Espresso ::"; $ Cup -> {$ method} Grind (@args); Nine, the destructor Perl tracks the number of links to the object, when the last application of an object is released to the memory pool, the object is Automatic destruction. The sector of the object occurs after the code is stopped, the script will end. For global variables, the designer has occurred after the last line of code is running. If you want to get control before the object is released, you can define the destroy () method. DESTROY () is called before the object will be released so that you can do some cleanup work. The DESTROY () function does not automatically call other DESTROY () functions, and Perl does not do built-in destructure work. If the constructor is multiple times, DESTROY () may need to call other class DESTROY () functions. When an object is released, all objects included are automatically released and destroyed. In general, it is not necessary to define the destroy () function, if needed, the form is as follows:
Sub destroy {## add code here. #}
Because of a variety of purposes, Perl uses simple, reference-based garbage collection system. The number of references to any object must be greater than zero, otherwise the memory of the object is released. When the program exits, a thorough lookup of Perl and destroys functions for garbage collection, and everything in the process is simply deleted. In the Unix class system, this is excessive, but this is indeed necessary in an in-room or multi-threaded environment. X. Inheritability methods are inherited by @ISA array, and the inheritance of variables must be clearly set. The following example creates two class bean.pm and coffee.pm, where Coffee.PM inherits some of the features of bean.pm. This example demonstrates how to inherit instance variables from the base class (or super class), which is called the constructor of the base class and adds its own instance variable to the new object. Bean.pm code is as follows:
Package bean; @isa = qw (exporter); @ @ e = qw (setBeantype); Sub New {MY $ TYPE = Shift; My $ this = {}; $ this -> {'bean'} = 'colorbian '; $ THIS; RETURN $ THIS;} ## this subroutine set the class namesub setBeantype {MY ($ Class, $ name) @__; $ class -> {' bean '} = $ name; print "Set Bean to $ Name / N"; 1;
In this class, set an anonymous hash table with $ this variable, set the 'bean' type to 'Colombian'. Method setBeantype () is used to change the 'bean' type, which uses the $ Class reference to get access to the object hash table. 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 item11 # 12 SETCOFEETYPE {13 My ($ Class, $ Name) = @_; 14 $ Class -> {'coffee'} = $ name; 15 print "set coffee type to $ name / n "; 16} 17 # 18 # Constructor19 # 20 Sub new {21 my $ type = shift; 22 my $ this = bean-> new (); #####
The second line of the Require bean; statement contains the bean.pm file and all related functions, and method setCoffeeType () is used to set the value of the local variable $ Class -> {'Coffee'}. In the constructor new (), $ this points to the pointer of the anonymous hash table returned by bean.pm, not in the local creation, the following two statements are created with the bean.pm constructor, respectively. The hash table is not related to the situation and inheritance: My $ this = {}; # 不 继 m $ this = $ THESUPERCLASS-> new (); # Inherit the following code demonstrate how to call inheritance:
1 #! / Usr / bin / perl2 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 ------------------------ / N " ; 9 $ CUP-> setBeantype ('Mixed'); 10 Print "Bean Type is now $ CUP -> {'bean'} / n"; 11 print "/ n ------------ ---------- / N "; 12 $ CUP-> SetCoffeetyPE ('Instant'); 13 Print" Type of Coffee: $ cup -> {'coffee' } / n "; the result of this code is as follows:
-------------------- Initial Values ------------ Coffee: Instantbean: Colombian ----------- --------- Change Bean Type --------- set bean to mixedbean type is now mixed ---------------- Change coffee TYPE ---------- Set coffee type to instanttype of coffee: instant
In the above code, the index of the index in the hasxiety in the hasxiety is the value of 'ben' and 'coffee' at the time of the object creation, and then the member function changes the value after the value is then output. Methods can have multiple parameters, and now add functions 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 cubes / n "if ($ sugar) PRINT "MAKING SOME Real" ================================================================ ====== / n ";}
This function can have three parameters, different numbers, value parameters produce different results, for example: 1 #! / Usr / bin / perl2 push (@ INC, 'PWD'); 3 Use coffee; 4 $ CUP = New Coffee; 5 # 6 # with no parameters7 # 8 print "/ n calling with no parameters: / n"; 9 $ CUP-> makecup; 10 # 11 # with one parameter12 # 13 print "/ n calling with one parameter: / n" 14 $ CUP-> Makecup ('1'); 15 # 16 # with Two Parameters17 # 18 Print "/ N Calling with Two Parameters: / N"; 19 $ CUP-> Makecup (1, '2'); 20 # 21 # with all three parameters22 # 23 print "/ n Calling with three parameters: / n"; 24 $ CUP-> Makecup ('1', 3, '1');
The result is output as follows:
Calling with no parameters: ================================== ================= ========================== caverling with one parameter: ================================================================================================================================================================================================================================ =============== Making a cupadd create =============================== === Calling with two parameters: =========================================== Making a cupadd created 2 sugar cubes = ================================= caverling with three parameters: ====================== ====================== Making a cupadd create some really addictive coffee; -) ============== ====================
In this example, the parameters of the function makecup () can be used for both a string, and the processing result is the same, and you can also divide these two types of data processing. In the process of parameters, the default value can be set, or different processing can also be given according to the number of actual input parameter values. XI, the benefit of the overload inheritance of the sub-class method is the function of obtaining the method of the base class output, and sometimes it needs to be overloaded to the base class to obtain more specific or different functions. The following is in the bean.pm class to join the method printepe (), the code is as follows: Sub printType {MY $ Class = Shift @_; print "The Type of Bean IS $ Class -> {'bean'} / n";}
Then update its @export array to output: @export = QW (setBeantype, prinTType); now call the function prinTtype (), there are three call methods:
$ Cup-> Coffee :: PrintType (); $ CUP-> PrintType (); $ CUP-> bean :: prinTtype ();
The output is as follows:
The Type of Bean Is Mixedthe Type of Bean Is Mixedthe Type of Bean IS Mixed
Why is it the same? Since the function prinTType () is not defined in the subclass, the method in the base class is actually called. If you want to make the subclasses have their own PrintType () function, you must define in the Coffee.PM class:
## rtine prints The Type of $ Class -> {'coffee'} # Sub PrintType {MY $ Class = Shift @_; print "The Type of coffee is $ class -> {'coffee'} / n";}
Then update its @Export arrays: @Export = QW (Setimports, Declaremain, Closemain, PrintType); Now output results become:
The Type of Coffee Is Instantthe Type of Coffee Is Instantthe Type of Bean IS Mixed
Now there is only a method of calling the subclass directly when it is given for the bean ::. So if you don't know how the base class name calls a base class method? The method is to use a pseudo-class reserved word Super ::. Use grammar in the class method such as $ this-> super :: function (... argument list ...); it will be found in the @isa list. Just now: Replacing Bean :: CUP-> Super :: printtype ();:::
The Type of Bean is Mixed
Twelve, the biggest advantage of some comments OOP of Perl class and object is the code reuse. OOP with data package hides some complex code, Perl package and module provide data package function via the MY function, but Perl does not guarantee that the subclass will not directly access the variables of the base class, which does not reduce the benefits of data packaging, Although this action can be done, it is a very bad programming style. note:
1. Be sure to access the class variables by way. 2, must not access the class variables directly from the outside of the module.
When writing a package, you should guarantee that the conditions needed to have or pass through parameters to it. Inside the package, it should be ensured that access to global variables is only accessed by reference to the reference. For static or global data to use, you should define locations in the base class, the subclays are obtained by calling the base class. Sometimes, the subclass may need to change this data. At this time, the base class may not know how to find new data, so it is best to define the reference, subclasses, and base classes to change by reference. This data. Finally, you will see the following objects and classes: Use coffee :: bean; the meaning of this sentence is "Coffee subdirectory of all directories in the @Inc array". If you move bean.pm to the ./coffee directory, the above example will work with this USE statement. Such benefits are code for organizing classes. Another example, the following statement: Use annother :: sub :: menu; means that the parameter variable is called the new () function of the constructor as the next subdirectory tree: ./another/Sub/Menu.pm instance variable is called instance variables. Example variables are used to initialize each instance of the object, for example, can use a new () function to give each instance of each instance of the object. Instance variables can be saved with anonymous hash table or an anonymous array. The code with the hash table is as follows:
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 saved with 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, $ TYI
}
When constructing an object, you can pass parameters as follows: $ mug = Cocoa :: new ('name' => 'top', 'x' => 10, 'y' => 20); operator => and comma operating suit The same, but => is well readable. The access method is as follows: Print "name = $ mug -> {'name'} / n"; print "x} / $ mug -> {'x'} / n"; print "y = $ mug -> {'y' } / n "; 5. The method of the method Perl class is just a Perl subroutine, that is, the usual member function. Perl's method definition does not provide any special syntax, but the first parameter of the specified method is an object or its referenced package. There are two ways: static methods and false methods. The first parameter of the static method is class name, the first parameter of the virtual method is the reference. Methods to deal with the first parameter determine whether it is still still or virtual. Static methods generally ignore the first parameters because they already know which class, the constructor is a static method. The virtual method usually first puts the first parameter Shift to the variable Self or THIS, and then uses the value to be used for normal reference. Such as: 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, the output of the method If you want to quote the Cocoa.pm package now, you will get a compilation error saying that the method is not found because Cocoa.pm has not been output yet. The output method requires an Exporter module, plus the following two lines in the beginning of the package: Require exporter; @ISA = QW (Exporter); these two lines contain the exporter.pm module and add the Exporter class name to the @ISA array for findings . Next, you can list your own class method in the @Export array. For example, if you want to output methods, Closemain and Declaremain, the statement is as follows: @Export = QW (DeclareMain, Closemain); the inheritance of the Perl class is implemented through the @ISA array. The @isa array does not need to be defined in any package, however, once it is defined, Perl regards it as a special array of directory names. It is similar to the @Inc array, @ INC is a search path containing files. The @ISA array contains a class (package) name, when a method is not found in the current package, go to the package in @ISA to find it. @ISA also contains the base class name inherited by the current class. All methods in the class must belong to the base class defined by the same class or an @isa array. If a method is not found in the @ISA array, Perl is looking for in the AutoLoad () subroutine, which is defined in the current packet. If you use the AutoLoad subroutine, you must call the AutoLoad.pm package with the USE AutoLoad; statement. The AutoLoad subroutine tries to load the call from the installed Perl library. If AutoLoad also fails, Perl will do the last attempt to the Universal class. If it is still failed, Perl generates an error on the unable to resolve functions. Seven, the method of calling to call an object has two methods, one is the reference (virtual method) of the object, one is to use the class name (static method). Of course, this method must have been output. Now add some methods to the Cocoa class, 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";} # ## routine declares the main function in a java script # SUB DECLAREMAIN {MY $ Class = Shift @_; MY ($ Name, $ EXTENDS, $ IMPLEMENTS) = @_; print "/ n public class $ name"; if ($ extend "{print" Extends ". $ Extend;}}}} {Print "import"} "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 ** create 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 class, below is the script code for creating a Java Applet source skeleton:
#! / usr / bin / Perluse Cocoa; $ CUP = New Cocoa; $ CUP-> SetimPorts ('Java.Io.inputStream', 'java.net. *'); $ Cup-> Declaremain ("msg", " Java.applet.applet "," runnable "); $ CUP-> Closemain ();
This script created a Java Applet called MSG, which extension has a java.applet.applet.applet.applet.Anable, where the last three rows can be written as follows:
Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); Cocoa :: Declaremain ($ CUP, "MSG", "Java.applet.applet", "runnable"); Cocoa :: Closemain ($ CUP);
The results of its operation are as follows:
/ *** Created by cocoa.pm ** use at own risk * / import java.io.inputstream; import java.net. *; Public class msg extends java.applet.applet imports runnable {} Note: If you use-> Operator call (also called indirect call), parameters must be enclosed in parentheses, such as $ cup-> setimports ('java.io.inputstream', 'java.net. *'); And double colon call such as: Cocoa :: Setimports ($ CUP, 'Java.io.InputStream', 'java.net. *'); can also remove the brackets: Cocoa :: Setimports $ CUP, 'Java.io.inputStream', 'Java.net. * '; Eight, the overload sometimes needs to specify which class of methods, such as two different classes have the same name method. Assuming that class espresso and qava define how to use :: operator Specify use of QAVA: $ Mess = Qava :: Grind ("Whole", "Lotta", "Bags"); QAVA :: Grind ($ Mess, "whole", "Lotta", "Bags"); which class can be selected according to the operation of the program, this can be implemented by using symbol reference: $ gethod = $ local? "Qava :: ": Espresso ::"; $ Cup -> {$ method} Grind (@args); Nine, the destructor Perl tracks the number of links to the object, when the last application of an object is released to the memory pool, the object is Automatic destruction. The sector of the object occurs after the code is stopped, the script will end. For global variables, the designer has occurred after the last line of code is running. If you want to get control before the object is released, you can define the destroy () method. DESTROY () is called before the object will be released so that you can do some cleanup work. The DESTROY () function does not automatically call other DESTROY () functions, and Perl does not do built-in destructure work. If the constructor is multiple times, DESTROY () may need to call other class DESTROY () functions. When an object is released, all objects included are automatically released and destroyed. In general, it is not necessary to define the destroy () function, if needed, the form is as follows:
Sub destroy {## add code here. #}
Because of a variety of purposes, Perl uses simple, reference-based garbage collection system. The number of references to any object must be greater than zero, otherwise the memory of the object is released. When the program exits, a thorough lookup of Perl and destroys functions for garbage collection, and everything in the process is simply deleted. In the Unix class system, this is excessive, but this is indeed necessary in an in-room or multi-threaded environment. X. Inheritability methods are inherited by @ISA array, and the inheritance of variables must be clearly set. The following example creates two class bean.pm and coffee.pm, where Coffee.PM inherits some of the features of bean.pm. This example demonstrates how to inherit instance variables from the base class (or super class), which is called the constructor of the base class and adds its own instance variable to the new object. Bean.pm code is as follows:
Package bean; @isa = qw (exporter); @ @ e = qw (setBeantype); Sub New {MY $ TYPE = Shift; My $ this = {}; $ this -> {'bean'} = 'colorbian '; $ THIS; RETURN $ THIS;} ## this subroutine set the class namesub setBeantype {MY ($ Class, $ name) @__; $ class -> {' bean '} = $ name; print "Set Bean to $ Name / N"; 1;
In this class, set an anonymous hash table with $ this variable, set the 'bean' type to 'Colombian'. Method setBeantype () is used to change the 'bean' type, which uses the $ Class reference to get access to the object hash table. 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 item11 # 12 SETCOFEETYPE {13 My ($ Class, $ Name) = @_; 14 $ Class -> {'coffee'} = $ name; 15 print "set coffee type to $ name / n "; 16} 17 # 18 # Constructor19 # 20 Sub new {21 my $ type = shift; 22 my $ this = bean-> new (); #####
The second line of the Require bean; statement contains the bean.pm file and all related functions, and method setCoffeeType () is used to set the value of the local variable $ Class -> {'Coffee'}. In the constructor new (), $ this points to the pointer of the anonymous hash table returned by bean.pm, not in the local creation, the following two statements are created with the bean.pm constructor, respectively. The hash table is not related to the situation and inheritance: My $ this = {}; # 不 继 m $ this = $ THESUPERCLASS-> new (); # Inherit the following code demonstrate how to call inheritance:
1 #! / Usr / bin / perl2 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 ------------------------ / N " ; 9 $ CUP-> setBeantype ('Mixed'); 10 Print "Bean Type is now $ CUP -> {'bean'} / n"; 11 print "/ n ------------ ---------- / N "; 12 $ CUP-> SetCoffeetyPE ('Instant'); 13 Print" Type of Coffee: $ cup -> {'coffee' } / n "; the result of this code is as follows:
-------------------- Initial Values ------------ Coffee: Instantbean: Colombian ----------- --------- Change Bean Type --------- set bean to mixedbean type is now mixed ---------------- Change coffee TYPE ---------- Set coffee type to instanttype of coffee: instant
In the above code, the index of the index in the hasxiety in the hasxiety is the value of 'ben' and 'coffee' at the time of the object creation, and then the member function changes the value after the value is then output. Methods can have multiple parameters, and now add functions 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 cubes / n "if ($ sugar) PRINT "MAKING SOME Real" ================================================================ ====== / n ";}
This function can have three parameters, different numbers, value parameters produce different results, for example: 1 #! / Usr / bin / perl2 push (@ INC, 'PWD'); 3 Use coffee; 4 $ CUP = New Coffee; 5 # 6 # with no parameters7 # 8 print "/ n calling with no parameters: / n"; 9 $ CUP-> makecup; 10 # 11 # with one parameter12 # 13 print "/ n calling with one parameter: / n" 14 $ CUP-> Makecup ('1'); 15 # 16 # with Two Parameters17 # 18 Print "/ N Calling with Two Parameters: / N"; 19 $ CUP-> Makecup (1, '2'); 20 # 21 # with all three parameters22 # 23 print "/ n Calling with three parameters: / n"; 24 $ CUP-> Makecup ('1', 3, '1');
The result is output as follows:
Calling with no parameters: ================================== ================= ========================== caverling with one parameter: ================================================================================================================================================================================================================================ =============== Making a cupadd create =============================== === Calling with two parameters: =========================================== Making a cupadd created 2 sugar cubes = ================================= caverling with three parameters: ====================== ====================== Making a cupadd create some really addictive coffee; -) ============== ====================
In this example, the parameters of the function makecup () can be used for both a string, and the processing result is the same, and you can also divide these two types of data processing. In the process of parameters, the default value can be set, or different processing can also be given according to the number of actual input parameter values. XI, the benefit of the overload inheritance of the sub-class method is the function of obtaining the method of the base class output, and sometimes it needs to be overloaded to the base class to obtain more specific or different functions. The following is in the bean.pm class to join the method printepe (), the code is as follows: Sub printType {MY $ Class = Shift @_; print "The Type of Bean IS $ Class -> {'bean'} / n";}
Then update its @export array to output: @export = QW (setBeantype, prinTType); now call the function prinTtype (), there are three call methods:
$ Cup-> Coffee :: PrintType (); $ CUP-> PrintType (); $ CUP-> bean :: prinTtype ();
The output is as follows:
The Type of Bean Is Mixedthe Type of Bean Is Mixedthe Type of Bean IS Mixed
Why is it the same? Since the function prinTType () is not defined in the subclass, the method in the base class is actually called. If you want to make the subclasses have their own PrintType () function, you must define in the Coffee.PM class:
## rtine prints The Type of $ Class -> {'coffee'} # Sub PrintType {MY $ Class = Shift @_; print "The Type of coffee is $ class -> {'coffee'} / n";}
Then update its @Export arrays: @Export = QW (Setimports, Declaremain, Closemain, PrintType); Now output results become:
The Type of Coffee Is Instantthe Type of Coffee Is Instantthe Type of Bean IS Mixed
Now there is only a method of calling the subclass directly when it is given for the bean ::. So if you don't know how the base class name calls a base class method? The method is to use a pseudo-class reserved word Super ::. Use grammar in the class method such as $ this-> super :: function (... argument list ...); it will be found in the @isa list. Just now: Replacing Bean :: CUP-> Super :: printtype ();:::
The Type of Bean is Mixed
Twelve, the biggest advantage of some comments OOP of Perl class and object is the code reuse. OOP with data package hides some complex code, Perl package and module provide data package function via the MY function, but Perl does not guarantee that the subclass will not directly access the variables of the base class, which does not reduce the benefits of data packaging, Although this action can be done, it is a very bad programming style. note:
1. Be sure to access the class variables by way. 2, must not access the class variables directly from the outside of the module.