⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch5.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
# Add code here.<BR>

#<BR>

}</FONT></TT>

</BLOCKQUOTE>

<P>

For most purposes, Perl uses a simple reference-based garbage

collection system. The number of references to any given object

at the time of garbage collection has to be greater than zero,

or else the memory for that object is freed. When your program

exits, an exhaustive search-and-destroy function in Perl does

the garbage collection. Everything in the process is summarily

deleted. In UNIX or UNIX-like systems, this may seem like a waste,

but it is actually quite necessary in embedded systems or in a

multithreaded environment.

<H2><A NAME="Inheritance"><FONT SIZE=5 COLOR=#FF0000>Inheritance</FONT></A>

</H2>

<P>

Methods in classes are inherited with the use of the paths in

the <TT><FONT FACE="Courier">@ISA</FONT></TT> array. Variables

have to be inherited and set up explicitly for inheritance. Let's

say you define a new class called <TT><FONT FACE="Courier">Bean.pm</FONT></TT>

to include some of the functionality that another class, <TT><FONT FACE="Courier">Coffee.pm</FONT></TT>,

will inherit.

<P>

The example in this section demonstrates how to inherit instance

variables from one class (also referred to as a <I>superclass</I>

or <I>base class</I>). The steps in inheritance require calling

the superclass's constructor and adding one's own instance variables

to the new object.

<P>

In this example, the <TT><FONT FACE="Courier">Coffee</FONT></TT>

class is the class that inherits values from the base class <TT><FONT FACE="Courier">Bean</FONT></TT>.

The two files are called <TT><FONT FACE="Courier">Coffee.pm</FONT></TT>

and <TT><FONT FACE="Courier">Bean.pm</FONT></TT>, respectively.

The code for <TT><FONT FACE="Courier">Bean.pm</FONT></TT> is shown

in Listing 5.12.

<HR>

<BLOCKQUOTE>

<B>Listing 5.12. The </B><TT><B><FONT FACE="Courier">Bean.pm</FONT></B></TT><B>

file.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 package Bean;<BR>

&nbsp;2 require Exporter;<BR>

&nbsp;3 <BR>

&nbsp;4 @ISA = qw(Exporter);<BR>

&nbsp;5 @EXPORT = qw(setBeanType);

<BR>

&nbsp;6 <BR>

&nbsp;7 sub new {<BR>

&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp; my $type = shift;<BR>

&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;

my $this = {};<BR>

10&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;{'Bean'} = 'Colombian';<BR>

11&nbsp;&nbsp;&nbsp;&nbsp; bless $this, $type;<BR>

12&nbsp;&nbsp;&nbsp;&nbsp; return $this;<BR>

13&nbsp;&nbsp;&nbsp;&nbsp; }<BR>

14 <BR>

15 #<BR>

16 # This subroutine sets the<BR>

17 sub setBeanType{<BR>

18&nbsp;&nbsp;&nbsp;&nbsp; my ($class, $name) =&nbsp;&nbsp;@_;

<BR>

19&nbsp;&nbsp;&nbsp;&nbsp; $class-&gt;{'Bean'} = $name;<BR>

20&nbsp;&nbsp;&nbsp;&nbsp; print &quot;Set bean to $name \n&quot;;

<BR>

21&nbsp;&nbsp;&nbsp;&nbsp; }<BR>

22 1;</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

In this listing, the <TT><FONT FACE="Courier">$this</FONT></TT>

variable sets a value in the anonymous hash for the <TT><FONT FACE="Courier">'Bean'</FONT></TT>

class to be <TT><FONT FACE="Courier">'Colombian'</FONT></TT>.

The <TT><FONT FACE="Courier">setBeanType</FONT></TT> function

method is also declared so that the item referred to by the word

<TT><FONT FACE="Courier">'Bean' </FONT></TT>is set for any class

that is sent in as an argument. Therefore, you can use this <TT><FONT FACE="Courier">setBeanType</FONT></TT>

function in other classes to set the value of any member whose

name is <TT><FONT FACE="Courier">'Bean'</FONT></TT>.

<P>

The subroutine for resetting the value of <TT><FONT FACE="Courier">'Bean'</FONT></TT>

uses the <TT><FONT FACE="Courier">$class</FONT></TT> reference

to get to the anonymous hash for the object. Remember that it

is a reference to this anonymous hash that created the reference

in the first place with the <TT><FONT FACE="Courier">new()</FONT></TT>

function.

<P>

The values in the <TT><FONT FACE="Courier">Bean</FONT></TT> class

are inherited by the <TT><FONT FACE="Courier">Coffee</FONT></TT>

class. The <TT><FONT FACE="Courier">Coffee.pm</FONT></TT> file

is shown in Listing 5.13.

<HR>

<BLOCKQUOTE>

<B>Listing 5.13. Using inheritance.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;# The Coffee.pm file to illustrate

inheritance.<BR>

&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;#

<BR>

&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;package Coffee;<BR>

&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;require

Exporter;<BR>

&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;require Bean;<BR>

&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;@ISA

= qw(Exporter, Bean);<BR>

&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;@EXPORT = qw(setImports, declareMain,

closeMain);<BR>

&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;

#<BR>

10&nbsp;&nbsp;&nbsp;&nbsp; # set item<BR>

11&nbsp;&nbsp;&nbsp;&nbsp; #<BR>

12&nbsp;&nbsp;&nbsp;&nbsp; sub setCoffeeType{<BR>

13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($class,$name)

=&nbsp;&nbsp;@_;<BR>

14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class-&gt;{'Coffee'}

= $name;<BR>

15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print

&quot;Set coffee type to $name \n&quot;;<BR>

16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

17&nbsp;&nbsp;&nbsp;&nbsp; #<BR>

18&nbsp;&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;constructor<BR>

19&nbsp;&nbsp;&nbsp;&nbsp; #<BR>

20&nbsp;&nbsp;&nbsp;&nbsp; sub new {<BR>

21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $type&nbsp;&nbsp;=

shift;<BR>

22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $this&nbsp;&nbsp;=

Bean-&gt;new();&nbsp;&nbsp;&nbsp;&nbsp; ##### &lt;-- LOOK HERE!!!

####<BR>

23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;{'Coffee'}

= 'Instant';&nbsp;&nbsp;# unless told otherwise<BR>

24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bless

$this, $type;<BR>

25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return

$this;<BR>

26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

27&nbsp;&nbsp;&nbsp;&nbsp; 1;</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Note the use of the <TT><FONT FACE="Courier">require Bean;</FONT></TT>

statement at line 6. (<A HREF="ch4.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch4.htm" >See Chapter 4</A>, &quot;Introduction

to Perl Modules,&quot; in the section titled &quot;Using Perl

Modules&quot; for the reasons why the <TT><FONT FACE="Courier">require</FONT></TT>

statement is used instead of the <TT><FONT FACE="Courier">use</FONT></TT>

statement.) This line forces the inclusion of the <TT><FONT FACE="Courier">Bean.pm</FONT></TT>

file and all its related functions without importing the functions

until compile time. Lines 12 through 16 define a subroutine to

use when resetting the value of the local variable in <TT><FONT FACE="Courier">$class-&gt;{'Coffee'}</FONT></TT>.

<P>

Look at the <TT><FONT FACE="Courier">new()</FONT></TT> constructor

for the <TT><FONT FACE="Courier">Coffee</FONT></TT> class. The

<TT><FONT FACE="Courier">$this</FONT></TT> reference points to

the anonymous hash returned by <TT><FONT FACE="Courier">Bean.pm</FONT></TT>,

not a hash created locally. In other words, the following statement

creates an entirely different hash that has nothing to do with

the hash created in the <TT><FONT FACE="Courier">Bean.pm</FONT></TT>

constructor.

<BLOCKQUOTE>

<TT><FONT FACE="Courier">my $this = {};  # This is not the way

to do it for inheritance.<BR>

my $this = $theSuperClass-&gt;new();  # this is the way.</FONT></TT>

</BLOCKQUOTE>

<P>

Listing 5.14 illustrates how to call these functions. 

<HR>

<BLOCKQUOTE>

<B>Listing 5.14. Using inheritance.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2 push (@Inc,'pwd');<BR>

&nbsp;3 use Coffee;<BR>

&nbsp;4 $cup = new Coffee;<BR>

&nbsp;5 print &quot;\n --------------------

Initial values ------------ \n&quot;;<BR>

&nbsp;6 print &quot;Coffee: $cup-&gt;{'Coffee'} \n&quot;;<BR>

&nbsp;7 print &quot;Bean:

$cup-&gt;{'Bean'} \n&quot;;<BR>

&nbsp;8 print &quot;\n -------------------- Change Bean Type ----------

\n&quot;;<BR>

&nbsp;9 $cup-&gt;setBeanType('Mixed');

<BR>

10 print &quot;Bean Type is now $cup-&gt;{'Bean'} \n&quot;;<BR>

11 print &quot;\n ------------------ Change Coffee Type ----------

\n&quot;;<BR>

12 $cup-&gt;setCoffeeType('Instant');<BR>

13 print &quot;Type of coffee: $cup-&gt;{'Coffee'} \n&quot;;</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

The initial values for the <TT><FONT FACE="Courier">'Bean'</FONT></TT>

and <TT><FONT FACE="Courier">'Coffee'</FONT></TT> indexes in the

anonymous hash for the object are printed first. The member functions

are called to set the values to different names and are printed

out.

<P>

Here is the output of the script:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">-------------------- Initial values ------------

<BR>

Coffee: Instant<BR>

Bean: Colombian<BR>

<BR>

 -------------------- Change Bean Type ----------<BR>

Set bean to Mixed<BR>

Bean Type is now Mixed<BR>

<BR>

 ------------------ Change Coffee Type ----------<BR>

Set coffee type to Instant<BR>

Type of coffee: Instant</FONT></TT>

</BLOCKQUOTE>

<P>

Methods can have several types of arguments. It's how you process

the arguments that counts. For example, you can add the method

shown in Listing 5.15 to the <TT><FONT FACE="Courier">Coffee.pm</FONT></TT>

module.

<HR>

<BLOCKQUOTE>

<B>Listing 5.15. Variable-length lists of parameters.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">1 sub makeCup {<BR>

2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($class, $cream, $sugar,

$dope) = @_;<BR>

3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n==================================

\n&quot;;<BR>

4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;Making a cup

\n&quot;;<BR>

5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;Add cream \n&quot;

if ($cream);<BR>

6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;Add $sugar sugar

cubes\n&quot; if ($sugar);<BR>

7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;Making some really

addictive coffee ;-) \n&quot; if ($dope);<BR>

8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;==================================

\n&quot;;<BR>

9 }</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

This function takes three arguments, but it processes them only

if it sees them. To test this functionality, consider the Perl

code shown in Listing 5.16.

<HR>

<BLOCKQUOTE>

<B>Listing 5.16. Testing variable length lists.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;#!/usr/bin/perl

<BR>

&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;push (@Inc,'pwd');<BR>

&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;use

Coffee;<BR>

&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;$cup = new Coffee;<BR>

&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;#

<BR>

&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;With no parameters

<BR>

&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;#

<BR>

&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n Calling&nbsp;&nbsp;with

no parameters: \n&quot;;<BR>

&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;$cup-&gt;makeCup;

<BR>

10&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

11&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;With one parameter<BR>

12&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

13&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n Calling&nbsp;&nbsp;with

one parameter: \n&quot;;<BR>

14&nbsp;&nbsp;&nbsp;&nbsp;$cup-&gt;makeCup('1');<BR>

15&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

16&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;With two parameters<BR>

17&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

18&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n Calling&nbsp;&nbsp;with

two parameters: \n&quot;;<BR>

19&nbsp;&nbsp;&nbsp;&nbsp;$cup-&gt;makeCup(1,'2');<BR>

20&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

21&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;With all three parameters

<BR>

22&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

23&nbsp;&nbsp;&nbsp;&nbsp;print &quot;\n Calling&nbsp;&nbsp;with

three parameters: \n&quot;;<BR>

24&nbsp;&nbsp;&nbsp;&nbsp;$cup-&gt;makeCup('1',3,'1');</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Line 9 calls the function with no parameters. In Line 14, the

call is with one parameter. The parameters are passed either as

strings or integers-something this particular method does not

care about (see lines 19 and 24). However, some methods you write

in the future may require this distinction. 

<P>

Here's the output from this program:

<BLOCKQUOTE>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -