📄 ch14.htm
字号:
Get the name of the class from the parameter array.<BR>Assign the rest of the parameters to the </I><TT><I>%params</I></TT><I>hash.<BR>Assign a refereNCe to one of the entries in the </I><TT><I>%Colors</I></TT><I>hash to </I><TT><I>$self</I></TT><I>.This will be used as the object refereNCe.<BR>Bless the hash entry into the </I><TT><I>Color</I></TT><I>class and return </I><TT><I>$self</I></TT><I>as the object refereNCe.<BR>Start the </I><TT><I>main</I></TT><I>namespace.<BR>Print a message on </I><TT><I>STDOUT</I></TT><I>.<BR>Call the constructor for the </I><TT><I>Pen</I></TT><I>class. Assign the object refereNCe to </I><TT><I>$item</I></TT><I>.<BR>Use </I><TT><I>%properties</I></TT><I>as a temporary value to simplify the derefereNCing process.<BR>Print the three property values to verify that the property initializationworked.</I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 14.5 14LST05.PL-How One Class Can Use orContain Another Class<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>package Inventory_item; sub new { my($class) = shift; my(%params) = @_; bless { "PART_NUM" => $params{"PART_NUM"}, "QTY_ON_HAND" => $params{"QTY_ON_HAND"} }, $class;}package Pen; @ISA = (Inventory_item); sub new { my($class) = shift; my(%params) = @_; my($self) = Inventory_item->new(@_); $self->{"INK_COLOR"} = Color->new($params{"INK_COLOR"}); return(bless($self, $class)); }package Color; print("Executing Color statements\n"); $colors{"blue"} = "Die Lot 13"; $colors{"red"} = "Die Lot 5"; sub new { my($class) = shift; my($param) = @_; my($self) = \$colors{$param}; return(bless($self, $class)); }package main; print("Executing main statements\n"); $pen = Pen->new( "PART_NUM" => "12A-34", "QTY_ON_HAND" => 34, "INK_COLOR" => "blue"); %properties = %{$pen}; print("The part number is " . $properties{'PART_NUM'} . "\n"); print("The quantity is " . $properties{'QTY_ON_HAND'} . "\n"); print("The ink color is " . ${$properties{'INK_COLOR'}} . "\n");</PRE></BLOCKQUOTE><HR><P>This program displays<BLOCKQUOTE><PRE>Executing Color statementsExecuting main statementsThe part number is 12A-34The quantity is 34The ink color is Die Lot 13</PRE></BLOCKQUOTE><P>Where to start? You already know about the <TT>Inventory_item</TT>class and the <TT>@ISA</TT> array.Let's look at the assignment to the <TT>INK_COLOR</TT>entry of the <TT>Pen</TT> class. Thisline, <TT>$self->{"INK_COLOR"}= Color->new($params{"INK_COLOR"});</TT>,is used to call the constructor for the <TT>Color</TT>class. The expression <TT>$params{"INK_COLOR"}</TT>passes the value of <TT>"blue"</TT>to the <TT>Color</TT> constructor,which returns a refereNCe to one of the colors in the <TT>%colors</TT>associative array.<P>You can tell that Perl executes all statements that are not insidefuNCtions because the <TT>print</TT>statement in the <TT>Color</TT> packageis executed before the <TT>print</TT>statement in the <TT>main</TT> package.This is why you can define hash entries inside the <TT>Color</TT>class. When variables are defined inside a package but outsidea fuNCtion, they are called <I>static</I> variables. You can accessone of the hash entries in the <TT>Color</TT>package like this: <TT>$Color::colors{"blue"}</TT>.<H2><A NAME="StaticVersusRegularMethodsandVariables"><FONT SIZE=5 COLOR=#FF0000>Static Versus Regular Methods and Variables</FONT></A></H2><P>You already learned that a static method is one that can be calledwithout needing an instantiated object. Actually, you can alsohave static variables as you saw in the last section. Static variablescan be used to emulate <I>constants</I>, values that don't change.Constants are very useful. For example, you can use them for taxrates, mathematical constants, and things such as state abbreviations.Here is an example using a small Perl script:<BLOCKQUOTE><PRE>package Math; $math{'PI'} = 3.1415;package main; print("The value of PI is $Math::math{'PI'}.\n");</PRE></BLOCKQUOTE><P>This program displays<BLOCKQUOTE><PRE>The value of PI is 3.1415.</PRE></BLOCKQUOTE><P>You can also do this:<BLOCKQUOTE><PRE>package Math; $PI = 3.1415;package main; print("The value of PI is $Math::PI.\n");</PRE></BLOCKQUOTE><P>Because you have been using a static method all along-the <TT>new()</TT>method-I'll take this opportunity to demonstrate a regular fuNCtion.Listing 14.6 shows how to use the <TT>UNIVERSAL</TT>package to define a utility fuNCtion that is available to allclasses. <P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Start a definition of the </I><TT><I>UNIVERSAL</I></TT><I>class.<BR>Define the </I><TT><I>lookup()</I></TT><I>method.<BR>DerefereNCe the object refereNCe (the first element of </I><TT><I>@_</I></TT><I>)and use the second parameter as the key into the anonymous hash.Return the value of the hash entry.<BR>Start a definition of the </I><TT><I>Inventory_item</I></TT><I>class.<BR>Define the constructor for the class.<BR>Assign the rest of the parameters to the </I><TT><I>%params</I></TT><I>hash.<BR>Bless the anonymous hash with the class name.<BR>Use </I><TT><I>%params</I></TT><I>to initialize the class properties.<BR>Start the </I><TT><I>main</I></TT><I>namespace.<BR>Call the constructor for the </I><TT><I>Inventory_item</I></TT><I>class. Assign the object refereNCe to </I><TT><I>$item</I></TT><I>.<BR>Print the two property values using the </I><TT><I>lookup()</I></TT><I>method to verify that the property initialization worked.</I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 14.6 14LST06.PL-Using a Static Method toRetrieve Class Properties<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>package UNIVERSAL; sub lookup { return(%{$_[0]}->{$_[1]}); }package Inventory_item; sub new { my($class) = shift; my(%params) = @_; my($self) = { }; $self->{"PART_NUM"} = $params{"PART_NUM"}; $self->{"QTY_ON_HAND"} = $params{"QTY_ON_HAND"}; return(bless($self, $class)); }package main; $item = Inventory_item->new("PART_NUM"=>"12A-34", "QTY_ON_HAND"=>34); print("The part number is " . $item->lookup('PART_NUM') . "\n"); print("The quantity is " . $item->lookup('QTY_ON_HAND') . "\n");</PRE></BLOCKQUOTE><HR><P>I don't think this example needs any further explanation, so let'suse the space normally reserved to further discussion of the listingand show you another utility fuNCtion instead. The <TT>printAll()</TT>fuNCtion shown here displays all the properties of a class, oryou can specify one or more properties to display:<BLOCKQUOTE><PRE>sub printAll { my($self) = shift; my(@keys) = @_ ? @_ : sort(keys(%{$self})); print("CLASS: $self\n"); foreach $key (@keys) { printf("\t%10.10s => $self->{$key}\n", $key); }}</PRE></BLOCKQUOTE><P>If you put this fuNCtion into the <TT>UNIVERSAL</TT>package, it will be available to any classes you define.<P>After constructing an inventory object, the statement <TT>$item->printAll();</TT>might display<BLOCKQUOTE><PRE>CLASS: Inventory_item=HASH(0x77ceac) PART_NUM => 12A-34 QTY_ON_HAN => 34</PRE></BLOCKQUOTE><P>and the statement <TT>$item->printAll('PART_NUM');</TT>might display<BLOCKQUOTE><PRE>CLASS: Inventory_item=HASH(0x77ceac) PART_NUM => 12A-34</PRE></BLOCKQUOTE><H2><A NAME="Summary"><FONT SIZE=5 COLOR=#FF0000>Summary</FONT></A></H2><P>This chapter served as an introduction to objects. It was notintended to turn you into an overnight object guru. I hope thatenough information was presented so you have an understandingof the object terminology and can read other people's programs.You can also create your own methods and properties. However,if you need to create more than a few small objects, considerreading a book devoted specifically to object-oriented programming.I give this advice because the relationships between objects canbecome complex quickly when more than five objects are being used.<P>You learned earlier in the chapter that object-oriented programminghas its own terminology. This terminology lets you think of objectsin a computer language independent manner. After describing theobject or class as a set of properties (information) and methods(fuNCtions), the class can be programmed using C++, Perl, or Delphi.The programming language is relegated to the role of an implementationdetail.<P>The four big coNCepts in object-oriented programming are abstraction,eNCapsulation, inheritaNCe, and polymorphism. Abstraction meansto isolate the access of a property from how it's stored. ENCapsulationmeans that properties and the methods that act on them are definedtogether. InheritaNCe means that one class (the child) can bederived from another (the parent), and the child class will haveall the properties and methods defined in the parent. Polymorphismmeans that the child class can override properties and methodsdefined in the parent simply by using the same property or methodname.<P>After defining these words, you read about creating some classesfor an inventory system; the <TT>Inventory_item</TT>and <TT>Pen</TT> classes were described.The <TT>Pen</TT> class was derivedfrom the <TT>Inventory_item</TT> class.These classes were used in examples to show how abstraction andpolymorphism work.<P>Next, you looked at object-oriented Perl scripts. You read thatit's good to keep all class property information in anonymoushashes and that the <TT>bless()</TT>fuNCtion is used to change the data type of a variable-even anonymousones.<P>You saw how to initialize properties by passing values to the<TT>new()</TT> constructor fuNCtion.With this technique, you can use named parameters and thereforecreate partially initialized objects if needed. Child classesin Perl will not automatically inherit properties from its parents.However, using anonymous hashes totally avoids this issue becausethe parent constructor can be explicitly called to create theobject. Then, the child can simply add entries to the anonymoushash.<P>You saw an example of how one class can contain another. The <TT>Pen</TT>class used this technique to hold an instaNCe of the <TT>Color</TT>class.<P>Static variables and methods are independent of any specific object.For example, the <TT>Color</TT> classused a static hash to hold values for the colors blue and red.Static variables can be accessed using the notation <TT>$Color::colors{"blue"}</TT>.Of course, only static hash variables use this notation, but scalarsand arrays are accessed similarly. You can use static methodslike <TT>new()</TT> to create newinstaNCes of a class.<P>You also saw that the <TT>@ISA</TT>array is used to hold a list of parent classes for the base class.In addition, you learned that the <TT>UNIVERSAL</TT>class is invisibly added to the end of the <TT>@ISA</TT>array-making it the the last class searched for an undefined method.The <TT>AUTOLOAD()</TT> method isnormally used to load undefined methods; however, in this chapter,it was used instead to display an error message telling whichmethod
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -