📄 ch5.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 5 -- Object-Oriented Programming in
Perl</TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 5</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Object-Oriented Programming in
Perl</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#IntroductiontoModules" >Introduction to Modules</A>
<UL>
<LI><A HREF="#TheThreeImportantRules" >The Three Important Rules</A>
</UL>
<LI><A HREF="#ClassesinPerl" >Classes in Perl</A>
<LI><A HREF="#CreatingaClass" >Creating a Class</A>
<LI><A HREF="#BlessingaConstructor" >Blessing a Constructor</A>
<UL>
<LI><A HREF="#InstanceVariables" >Instance Variables</A>
</UL>
<LI><A HREF="#Methods" >Methods</A>
<LI><A HREF="#ExportingMethodswithExporterpm" >Exporting Methods with Exporter.pm</A>
<LI><A HREF="#InvokingMethods" >Invoking Methods</A>
<LI><A HREF="#Overrides" >Overrides</A>
<LI><A HREF="#Destructors" >Destructors</A>
<LI><A HREF="#Inheritance" >Inheritance</A>
<LI><A HREF="#OverridingMethods" >Overriding Methods</A>
<LI><A HREF="#AFewCommentsAboutClassesandObjects" >A Few Comments About Classes and Objects in Perl</A>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<P>
This chapter covers the object-oriented programming (OOP) features
of Perl. You'll see how to construct objects in Perl as well as
how to use the OOP features offered by Perl. You'll also learn
about inheritance, overriding of methods, and data encapsulation.
<H2><A NAME="IntroductiontoModules"><FONT SIZE=5 COLOR=#FF0000>Introduction
to Modules</FONT></A></H2>
<P>
A <I>module</I> is also referred to as a <I>package</I>. Objects
in Perl are based on references to data items within a package.
An <I>object</I> in Perl is simply a reference to something that
knows which class it belongs to. For more information, you can
consult the <TT><FONT FACE="Courier">perlmod</FONT></TT> and <TT><FONT FACE="Courier">perlobj</FONT></TT>
text files at <TT><A HREF="http://www.metronet.com/" tppabs="http://www.metronet.com/">http://www.metronet.com</A></TT>.
These files are the primary source of information on the Internet
about Perl modules.
<P>
When performing object-oriented programming with other languages,
you declare a class and then create (instantiate) <I>objects</I>
of that class. All objects of a particular class behave in a certain
way, which is governed by the <I>methods</I> of the class to which
the object belongs. You create classes by defining new ones or
by <I>inheriting</I> properties from an existing class.
<P>
For programmers already familiar with object-oriented principles,
this will all seem familiar. Perl is, and pretty much always has
been, an object-oriented language. In Perl 4, the use of packages
gave you different symbol tables from which to choose your symbol
names. In Perl 5, the syntax has changed a bit, and the use of
objects has been formalized somewhat.
<H3><A NAME="TheThreeImportantRules">The Three Important Rules</A>
</H3>
<P>
The following three declarations are extremely important to understanding
how objects, classes, and methods work in Perl. Each is covered
in more detail in the rest of the chapter.
<UL>
<LI><FONT COLOR=#000000>A </FONT><I>class</I> is a Perl package.
The package for a class provides the methods for objects.
<LI><FONT COLOR=#000000>A </FONT><I>method</I> is a Perl subroutine.
The only catch with writing methods is that the name of the class
is the first argument.
<LI><FONT COLOR=#000000>An </FONT><I>object</I> in Perl is a reference
to some data item within the class.
</UL>
<H2><A NAME="ClassesinPerl"><FONT SIZE=5 COLOR=#FF0000>Classes
in Perl</FONT></A></H2>
<P>
This point is important enough to repeat: A Perl class is simply
a package. When you see a Perl document referring to a <I>class</I>,
think <I>package</I>. Also, both <I>package</I> and <I>module</I>
mean the same thing. For C programmers, it's easy to use <TT><FONT FACE="Courier">::</FONT></TT>
notation for classes and <TT><FONT FACE="Courier">-></FONT></TT>
for pointing to structure elements and class members.
<P>
One of the key features of OOP in any object-oriented language
is that of inheritance. This is where new classes can be created
by adding new features to existing classes. The inheritance feature
offered by Perl is not the same as you would expect in other object-oriented
languages. Perl classes inherit methods only. You have to use
your own mechanisms to implement data inheritance.
<P>
Because each class is a package, it has its own name space with
its own associative array of symbol names. Therefore, each class
can have its own independent set of symbol names. As with package
references, you can address the variables in a class with the
<TT><FONT FACE="Courier">'</FONT></TT> operator. Therefore, members
of a class are addressed as <TT><FONT FACE="Courier">$class'$member</FONT></TT>.
In Perl 5, you can use the double colon instead of <TT><FONT FACE="Courier">'</FONT></TT>
to get the reference. Thus, <TT><FONT FACE="Courier">$class'member</FONT></TT>
is the same as <TT><FONT FACE="Courier">$class::$member</FONT></TT>.
<H2><A NAME="CreatingaClass"><FONT SIZE=5 COLOR=#FF0000>Creating
a Class</FONT></A></H2>
<P>
This section covers the requisite steps to take when you create
a new class. This chapter covers the semantics in the creation
of a very simple class, called <TT><FONT FACE="Courier">Invest</FONT></TT>,
for printing the required parts of a simple Java application source
code file. No, you will not become a Java expert, nor does this
package require you to have any experience in Java. The concept
of creating a class is what you're concerned with. For example,
this chapter could just as easily have been on creating a phone
book application, but how many such examples have you seen to
date in books? You'll use a different example this time.
<P>
First of all, you need to create a package file called <TT><FONT FACE="Courier">Cocoa.pm</FONT></TT>.
The <TT><FONT FACE="Courier">.pm</FONT></TT> extension is the
default extension for packages; it stands for Perl Module. A module
is a package, and a package is a class for all practical purposes.
Before you do anything else to the file, place a <TT><FONT FACE="Courier">1;</FONT></TT>
in the file. As you add more lines to the package file, make sure
you have <TT><FONT FACE="Courier">1;</FONT></TT> as the last line
of this file. The basic structure of the file is shown in Listing
5.1.
<HR>
<BLOCKQUOTE>
<B>Listing 5.1. The package template.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 package Cocoa;<BR>
2 #<BR>
3 # Put "require"
statements in for all required,imported packages<BR>
4 #<BR>
5 <BR>
6 #<BR>
7 # Just add code here
<BR>
8 #<BR>
9<BR>
10 1; # terminate the package with the required
1;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
It's important that you remember to always keep the required <TT><FONT FACE="Courier">1;</FONT></TT>
line as the last of the package file. This statement is required
for all packages in Perl.
<P>
Now you're ready to add your methods to this package and make
this a class. The first method you would probably want to add
is the <TT><FONT FACE="Courier">new()</FONT></TT> method, which
should be called to create a new object. The <TT><FONT FACE="Courier">new()</FONT></TT>
method is the constructor for the object.
<H2><A NAME="BlessingaConstructor"><FONT SIZE=5 COLOR=#FF0000>Blessing
a Constructor</FONT></A></H2>
<P>
A <I>constructor</I> is a Perl subroutine in a class that returns
a reference to something that has the class name attached to it.
Connecting a class name with a reference is referred to as <I>blessing</I>
an object. The function to establish this connection is <TT><FONT FACE="Courier">bless</FONT></TT>.
Here's the syntax for the <TT><FONT FACE="Courier">bless</FONT></TT>
function:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">bless YeReference [,<I>classname</I>]</FONT></TT>
</BLOCKQUOTE>
<P>
<TT><FONT FACE="Courier">YeReference</FONT></TT> is the reference
to the object being blessed. <TT><I><FONT FACE="Courier">classname</FONT></I></TT>
is optional and specifies the name of the package from which this
object will have methods. If <TT><I><FONT FACE="Courier">classname</FONT></I></TT>
is not specified, the name of the currently used package is used
instead. Thus, the way to create a constructor in Perl is to return
a reference to an internal structure that has been blessed into
this class. The initial <TT><FONT FACE="Courier">Cocoa.pm</FONT></TT>
package is shown in Listing 5.2.
<HR>
<BLOCKQUOTE>
<B>Listing 5.2. The first pass at the </B><TT><B><FONT FACE="Courier">new()</FONT></B></TT><B>
function.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">1 package Cocoa;<BR>
2 <BR>
3 sub new {<BR>
4 my $this = {}; # Create an
anonymous hash, and #self points to it.<BR>
5 bless $this;
# Connect the hash to the package Cocoa.<BR>
6 return $this;
# Return the reference to the hash.<BR>
7 }<BR>
8 <BR>
9 1;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">{}</FONT></TT> constructs a reference
to an empty hash. The returned value to this hash is assigned
to the local variable <TT><FONT FACE="Courier">$this</FONT></TT>.
The <TT><FONT FACE="Courier">bless()</FONT></TT> function takes
that reference to <TT><FONT FACE="Courier">$this</FONT></TT> and
tells the object it references that it's now <TT><FONT FACE="Courier">Cocoa</FONT></TT>
and then returns the reference.
<P>
The returned value to the calling function now refers to this
anonymous hash. On returning from the <TT><FONT FACE="Courier">new()</FONT></TT>
function, the <TT><FONT FACE="Courier">$this</FONT></TT> reference
is destroyed, but the calling function keeps a reference to this
hash. Therefore, the reference count to the hash will not be zero,
and Perl keeps the hash in memory. You do not have to keep the
hash in memory, but it's nice to have it around for reference
later.
<P>
To create an object, you make a call like this one:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$cup = new Cocoa;</FONT></TT>
</BLOCKQUOTE>
<P>
The code is Listing 5.3 shows you how to use this package to create
the constructor.
<HR>
<BLOCKQUOTE>
<B>Listing 5.3. Using the </B><TT><B><FONT FACE="Courier">Cocoa</FONT></B></TT><B>
class.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">1 #!/usr/bin/perl<BR>
2 push (@Inc,'pwd');<BR>
3 use Cocoa;<BR>
4 $cup = new Cocoa;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The first line refers to the location of the Perl interpreter
to use. Your Perl interpreter may be located at <TT><FONT FACE="Courier">/usr/local/bin/perl</FONT></TT>
or wherever you installed it.
<P>
In line 2, the local directory is added to the search path in
<TT><FONT FACE="Courier">@Inc</FONT></TT> for the list of paths
to use when the Perl interpreter is looking for a package. You
can create your module in a different directory and specify the
path explicitly there. Had I created the package in <TT><FONT FACE="Courier">/home/khusain/test/scripts/</FONT></TT>,
line 2 would read as this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">push (@Inc,"/home/khusain/test/scripts");</FONT></TT>
</BLOCKQUOTE>
<P>
In line 3 you include the package <TT><FONT FACE="Courier">Cocoa.pm</FONT></TT>
to get all the functionality in your script. The <TT><FONT FACE="Courier">use</FONT></TT>
statement asks Perl to look in the <TT><FONT FACE="Courier">@Inc</FONT></TT>
path for a file called <TT><FONT FACE="Courier">Cocoa.pm</FONT></TT>
and include it in the copy of the source file being parsed. The
<TT><FONT FACE="Courier">use</FONT></TT> statement is required
if you want to work with a class.
<P>
Line 4 creates the <TT><FONT FACE="Courier">Cocoa</FONT></TT>
object by calling the <TT><FONT FACE="Courier">new</FONT></TT>
function on it. Now comes the beautiful (yet confusing and powerful)
part of Perl. There is more than one way to do this. You can rewrite
line 3 as this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$cup = Cocoa->new();</FONT></TT>
</BLOCKQUOTE>
<P>
Or if you are a C-programming hack, you can use the double colons
(<TT><FONT FACE="Courier">::</FONT></TT>) to force the function
<TT><FONT FACE="Courier">new()</FONT></TT> from the <TT><FONT FACE="Courier">Cocoa</FONT></TT>
package. Thus, line 4 could also be written as this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">$cup = Cocoa::new();</FONT></TT>
</BLOCKQUOTE>
<P>
There is nothing preventing you from adding more code in the constructor
than what is shown here. For this <TT><FONT FACE="Courier">Cocoa.pm</FONT></TT>
module, if you would like to print a disclaimer when each object
is created, you can. For example, you can add statements like
these in the constructor for debugging purposes:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">print "Hey! I am alive" if
($debuglevel > 1); </FONT></TT>
</BLOCKQUOTE>
<P>
This way, you can set a variable<TT><FONT FACE="Courier"> $debuglevel</FONT></TT>
to a numeric value of <TT><FONT FACE="Courier"> 2</FONT></TT>
or greater in your program to display the debug message shown
every time a new <TT><FONT FACE="Courier">Cocoa</FONT></TT> object
is created. Usually, you would like to initialize variables in
a constructor before any processing is done with the object. For
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -