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

📄 ch12_04.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 2 页
字号:
$shelob = Spider-&gt;spawn;</pre></blockquote>And each object would be of the proper class.This even works indirectly, as in:<blockquote><pre class="programlisting">$type  = "Spider";$shelob = $type-&gt;spawn;         # same as "Spider"-&gt;spawn</pre></blockquote>That's still a class method, not an instance method, because itsinvocant holds a string and not a reference.</p><p><a name="INDEX-2421"></a>If <tt class="literal">$type</tt> were an object instead of a class name, the previousconstructor definition wouldn't have worked, because <tt class="literal">bless</tt> needs aclass name.  But for many classes, it makes sense to use an existingobject as the template from which to create another.  In these cases,you can design your constructors so that they work with either objectsor class names:<blockquote><pre class="programlisting">sub spawn {    my $invocant = shift;    my $class    = ref($invocant) || $invocant;  # Object or class name    my $self     = { };    bless($self, $class);    return $self;}</pre></blockquote></p><h3 class="sect2">12.4.2. Initializers</h3><p><a name="INDEX-2422"></a><a name="INDEX-2423"></a><a name="INDEX-2424"></a><a name="INDEX-2425"></a><a name="INDEX-2426"></a><a name="INDEX-2427"></a><a name="INDEX-2428"></a><a name="INDEX-2429"></a>Most objects maintain internal information that is indirectlymanipulated by the object's methods.  All our constructors so far havecreated empty hashes, but there's no reason to leave them empty.  Forinstance, we could have the constructor accept extra arguments tostore into the hash as key/value pairs.  The OO literature oftenrefers to such data as <em class="emphasis">properties</em>, <em class="emphasis">attributes</em>, <em class="emphasis">accessors</em>,<em class="emphasis">member data</em>, <em class="emphasis">instance data</em>, or <em class="emphasis">instance variables</em>.  Thesection "Instance Variables" later in this chapter discusses attributes in more detail.</p><p>Imagine a <tt class="literal">Horse</tt> class with instance attributes like "name" and"color":<blockquote><pre class="programlisting">$steed = Horse-&gt;new(name =&gt; "Shadowfax", color =&gt; "white");</pre></blockquote>If the object is implemented as a hash reference, the key/value pairscan be interpolated directly into the hash once the invocant isremoved from the argument list:<blockquote><pre class="programlisting">sub new {    my $invocant = shift;    my $class = ref($invocant) || $invocant;    my $self = { @_ };          # Remaining args become attributes    bless($self, $class);       # Bestow objecthood    return $self;}</pre></blockquote><a name="INDEX-2430"></a><a name="INDEX-2431"></a>This time we used a method named <tt class="literal">new</tt> for theclass's constructor, which just might lull C++ programmers intothinking they know what's going on.  But Perl doesn't consider"<tt class="literal">new</tt>" to be anything special; you may name yourconstructors whatever you like.  Any method that happens to create andreturn an object is a de facto constructor.  In general, we recommendthat you name your constructors whatever makes sense in the context ofthe problem you're solving.  For example, constructors in the<tt class="literal">Tk</tt> module are named after the widgets they create.In the <tt class="literal">DBI</tt> module, a constructor named<tt class="literal">connect</tt> returns a database handle object, andanother constructor named <tt class="literal">prepare</tt> is invoked as aninstance method and returns a statement handle object.  But if thereis no suitable context-specific constructor name,<tt class="literal">new</tt> is perhaps not a terrible choice.  Then again,maybe it's not such a bad thing to pick a random name to force peopleto read the interface contract (meaning the class documentation)before they use its constructors.</p><p>Elaborating further, you can set up your constructor with defaultkey/value pairs, which the user could later override by supplying themas arguments:<blockquote><pre class="programlisting">sub new {    my $invocant = shift;    my $class   = ref($invocant) || $invocant;    my $self = {        color  =&gt; "bay",        legs   =&gt; 4,        owner  =&gt; undef,        @_,                 # Override previous attributes    };    return bless $self, $class;}$ed       = Horse-&gt;new;                    # A 4-legged bay horse$stallion = Horse-&gt;new(color =&gt; "black");  # A 4-legged black horse</pre></blockquote>This <tt class="literal">Horse</tt> constructor ignores its invocant's existing attributeswhen used as an instance method.  You could create a secondconstructor designed to be called as an instance method, and ifdesigned properly, you could use the values from the invoking object asdefaults for the new one:<blockquote><pre class="programlisting">$steed  = Horse-&gt;new(color =&gt; "dun");$foal   = $steed-&gt;clone(owner =&gt; "EquuGen Guild, Ltd.");sub clone {    my $model = shift;    my $self  = $model-&gt;new(%$model, @_);    return $self;     # Previously blessed by -&gt;new}</pre></blockquote>(You could also have rolled this functionality directly into <tt class="literal">new</tt>,but then the name wouldn't quite fit the function.)</p><p>Notice how even in the <tt class="literal">clone</tt> constructor, we don't hardcode thename of the <tt class="literal">Horse</tt> class.  We have the original object invoke itsown <tt class="literal">new</tt> method, whatever that may be.  If we had written that as<tt class="literal">Horse-&gt;new</tt> instead of <tt class="literal">$model-&gt;new</tt>, then the classwouldn't have facilitated inheritance by a <tt class="literal">Zebra</tt> or <tt class="literal">Unicorn</tt>class.  You wouldn't want to clone Pegasus and suddenly find yourselfwith a horse of a different color.</p><p><a name="INDEX-2432"></a>Sometimes, however, you have the opposite problem: rather thantrying to share one constructor among several classes, you're trying tohave several constructors share one class's object.  This happenswhenever a constructor wants to call a base class's constructor to dopart of the construction work.  Perl doesn't do hierarchicalconstruction for you.  That is, Perl does not automatically call theconstructors (or the destructors) for any base classes of the classrequested, so your constructor will have to do that itself and then addany additional attributes the derived class needs.  So the situation isnot unlike the <tt class="literal">clone</tt> routine, except that instead of copying anexisting object into the new object, you want to call your base class'sconstructor and then transmogrify the new base object into your newderived object.</p><a name="INDEX-2433"></a><a name="INDEX-2434"></a><!-- BOTTOM NAV BAR --><hr width="515" align="left"><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch12_03.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0"></a></td><td align="right" valign="top" width="172"><a href="ch12_05.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">12.3. Method Invocation</td><td align="center" valign="top" width="171"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0"></a></td><td align="right" valign="top" width="172">12.5. Class Inheritance</td></tr></table></div><hr width="515" align="left"><!-- LIBRARY NAV BAR --><img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2001</a> O'Reilly &amp; Associates. All rights reserved.</font></p><map name="library-map"> <area shape="rect" coords="2,-1,79,99" href="../index.htm"><area shape="rect" coords="84,1,157,108" href="../perlnut/index.htm"><area shape="rect" coords="162,2,248,125" href="../prog/index.htm"><area shape="rect" coords="253,2,326,130" href="../advprog/index.htm"><area shape="rect" coords="332,1,407,112" href="../cookbook/index.htm"><area shape="rect" coords="414,2,523,103" href="../sysadmin/index.htm"></map><!-- END OF BODY --></body></html>

⌨️ 快捷键说明

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