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

📄 ch13_10.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 13.9. Writing an Inheritable Class (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:42:25Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch13_01.htm"TITLE="13. Classes, Objects, and Ties"><LINKREL="prev"HREF="ch13_09.htm"TITLE="13.8. Determining Subclass Membership"><LINKREL="next"HREF="ch13_11.htm"TITLE="13.10. Accessing Overridden Methods"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_09.htm"TITLE="13.8. Determining Subclass Membership"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.8. Determining Subclass Membership"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch13_01.htm"TITLE="13. Classes, Objects, and Ties"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_11.htm"TITLE="13.10. Accessing Overridden Methods"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.10. Accessing Overridden Methods"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch13-23209">13.9. Writing an Inheritable Class</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1151">Problem<ACLASS="indexterm"NAME="ch13-idx-1000004562-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004562-1"></A></A></H3><PCLASS="para">You're not sure whether you've designed your class robustly enough to be inherited.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1157">Solution</A></H3><PCLASS="para">Use the "empty subclass test" on your class.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1163">Discussion</A></H3><PCLASS="para">Imagine you've implemented a class called Person that supplies a constructor called <CODECLASS="literal">new</CODE>, and methods like <CODECLASS="literal">age</CODE> and <CODECLASS="literal">name</CODE>. Here's the straightforward implementation:</P><PRECLASS="programlisting">package Person;sub new {    my $class = shift;    my $self  = { };    return bless $self, $class;} sub name {    my $self = shift;    $self-&gt;{NAME} = shift if @_;    return $self-&gt;{NAME};} sub age {    my $self = shift;    $self-&gt;{AGE} = shift if @_;    return $self-&gt;{AGE};} </PRE><PCLASS="para">You might use the class in this way:</P><PRECLASS="programlisting">use Person;my $dude = Person-&gt;<CODECLASS="literal">new()</CODE>;$dude-&gt;name(&quot;Jason&quot;);$dude-&gt;age(23);printf &quot;%s is age %d.\n&quot;, $dude-&gt;name, $dude-&gt;age;</PRE><PCLASS="para">Now, consider another class, the one called Employee:</P><PRECLASS="programlisting">package Employee;use Person;@ISA = (&quot;Person&quot;);1;</PRE><PCLASS="para">There's not a lot to that one. All it's doing is loading in class Person and stating that Employee will inherit any needed methods from Person. Since Employee has no methods of its own, it will get all of its methods from Person. We rely upon an Employee to behave just like a Person.</P><PCLASS="para">Setting up an empty class like this is called the <EMCLASS="emphasis">empty base class test</EM><ACLASS="indexterm"NAME="ch13-idx-1000004570-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004570-1"></A> ; that is, it creates a derived class that does nothing but inherit from a base class. If the original base class has been designed properly, then the new derived class can be used as a drop-in replacement for the old one. This means you should be able to change just the class name and everything will still work:</P><PRECLASS="programlisting">use Employee;my $empl = Employee-&gt;<CODECLASS="literal">new()</CODE>;$empl-&gt;name(&quot;Jason&quot;);$empl-&gt;age(23);printf &quot;%s is age %d.\n&quot;, $empl-&gt;name, $empl-&gt;age;</PRE><PCLASS="para">By proper design, we mean using only the two-argument form of <CODECLASS="literal">bless</CODE>, avoiding any direct access of class data, and exporting nothing. In the <CODECLASS="literal">Person::new()</CODE> function defined above, we were careful to do these things. We use some package data in the constructor, but the reference to this is stored on the object itself. Other methods access package data via that reference, so we should be okay.</P><PCLASS="para"><ACLASS="indexterm"NAME="ch13-idx-1000005301-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000005301-1"></A>Why did we say the <CODECLASS="literal">Person::new</CODE> <EMCLASS="emphasis">function </EM> &nbsp;-   is that not actually a method? A method is just a function that expects as its first argument a class name (package) or object (blessed reference). <CODECLASS="literal">Person::new</CODE> is the function that the <CODECLASS="literal">Person-&gt;new</CODE> method and the <CODECLASS="literal">Employee-&gt;new</CODE> method both end up calling. Although a method call looks a lot like a function call, they aren't the same. If you treat them as the same, very soon you'll be left with nothing but broken programs. First, the actual underlying calling conventions are different: method calls get an extra argument. Second, function calls don't do inheritance, but methods do.</P><TABLECLASS="informaltable"BORDER="1"CELLPADDING="3"><THEADCLASS="thead"><TRCLASS="row"VALIGN="TOP"><THCLASS="entry"ALIGN="LEFT"ROWSPAN="1"COLSPAN="1"><PCLASS="para">Method Call</P></TH><THCLASS="entry"ALIGN="LEFT"ROWSPAN="1"COLSPAN="1"><PCLASS="para">Resulting Function Call</P></TH></TR></THEAD><TBODYCLASS="tbody"><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">Person-&gt;new()</CODE></P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">Person::new(&quot;Person&quot;)</CODE></P></TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">Employee-&gt;new()</CODE></P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">Person::new(&quot;Employee&quot;)</CODE></P></TD></TR></TBODY></TABLE><PCLASS="para">If you got in the habit of calling:</P><PRECLASS="programlisting">$him = Person::<CODECLASS="literal">new()</CODE>;               # WRONG</PRE><PCLASS="para">you'd have a subtle problem, because the function wouldn't get an argument of "Person" as it is expecting, and so it couldn't bless into the passed-in class. Still worse, you'd probably want to try to call <CODECLASS="literal">Employee::new()</CODE> also. But there is no such function! It's just an inherited method call.</P><PCLASS="para">So, don't use function calls when you mean to call a method.<ACLASS="indexterm"NAME="ch13-idx-1000004572-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004572-1"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1257">See Also</A></H3><PCLASS="para"><ICLASS="filename">perltoot </I>(1), <ICLASS="filename">perlobj </I>(1), and <ICLASS="filename">perlbot </I>(1); <ACLASS="olink"HREF="../prog/ch05_01.htm">Chapter 5</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; <ACLASS="xref"HREF="ch13_02.htm"TITLE="Constructing an Object">Recipe 13.1</A>; <ACLASS="xref"HREF="ch13_11.htm"TITLE="Accessing Overridden Methods">Recipe 13.10</A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_09.htm"TITLE="13.8. Determining Subclass Membership"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.8. Determining Subclass Membership"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch13_11.htm"TITLE="13.10. Accessing Overridden Methods"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.10. Accessing Overridden Methods"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">13.8. Determining Subclass Membership</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">13.10. Accessing Overridden Methods</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>

⌨️ 快捷键说明

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