📄 ch13_11.htm
字号:
<HTML><HEAD><TITLE>Recipe 13.10. Accessing Overridden Methods (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:42:26Z"><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_10.htm"TITLE="13.9. Writing an Inheritable Class"><LINKREL="next"HREF="ch13_12.htm"TITLE="13.11. Generating Attribute Methods Using AUTOLOAD"></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_10.htm"TITLE="13.9. Writing an Inheritable Class"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.9. Writing an Inheritable Class"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_12.htm"TITLE="13.11. Generating Attribute Methods Using AUTOLOAD"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.11. Generating Attribute Methods Using AUTOLOAD"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch13-33387">13.10. Accessing Overridden Methods</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1265">Problem<ACLASS="indexterm"NAME="ch13-idx-1000004577-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004577-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000004577-2"></A><ACLASS="indexterm"NAME="ch13-idx-1000004577-3"></A><ACLASS="indexterm"NAME="ch13-idx-1000004577-4"></A><ACLASS="indexterm"NAME="ch13-idx-1000004577-5"></A></A></H3><PCLASS="para">Your constructor method overrides the constructor of a parent class. You want your constructor to call the parent class's constructor.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1271">Solution</A></H3><PCLASS="para">Learn about the special class, <ACLASS="indexterm"NAME="ch13-idx-1000004583-0"></A>SUPER.</P><PRECLASS="programlisting">sub meth { my $self = shift; $self->SUPER::<CODECLASS="literal">meth()</CODE>;}</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1285">Discussion</A></H3><PCLASS="para">In languages like C++ where constructors don't actually allocate memory but just initialize the object, all base class constructors are automatically called for you. In languages like Java and Perl, you have to call them yourself.</P><PCLASS="para">To call a method in a particular class, the notation <CODECLASS="literal">$self->SUPER::meth()</CODE> is used. This is an extension of the regular notation to start looking in a particular base class. It is only valid from within an overridden method. Here's a comparison of styles:</P><PRECLASS="programlisting">$self-><CODECLASS="literal">meth();</CODE> # Call wherever first meth is found$self->Where::<CODECLASS="literal">meth();</CODE> # Start looking in package "Where"$self->SUPER::<CODECLASS="literal">meth(); </CODE> # Call overridden version</PRE><PCLASS="para">Simple users of the class should probably limit themselves to the first one. The second is possible, but not suggested. The last must only be called from within the overridden method.</P><PCLASS="para">An overriding constructor should call its SUPER's constructor to allocate and bless the object, limiting itself to instantiating any data fields needed. It makes sense here to separate the object allocation code from the object initialization code. We'll name it with a leading underscore, a convention indicating a nominally private method. Think of it as a "Do Not Disturb" sign.</P><PRECLASS="programlisting">sub new { my $classname = shift; # What class are we constructing? my $self = $classname->SUPER::new(@_); $self->_init(@_); return $self; # And give it back} sub _init { my $self = shift; $self->{START} = time(); # init data fields $self->{AGE} = 0; $self->{EXTRA} = { @_ }; # anything extra}</PRE><PCLASS="para">Both <CODECLASS="literal">SUPER::new</CODE> and <CODECLASS="literal">_init</CODE> have been called with any remaining arguments. That way the user might pass other field initializers in, as in:</P><PRECLASS="programlisting">$obj = Widget->new( haircolor => red, freckles => 121 );</PRE><PCLASS="para">Whether you store these user parameters in their own extra hash or not is up to you.</P><PCLASS="para">Note that SUPER only works on the first overridden method. If your <CODECLASS="literal">@ISA</CODE> array has several classes, it only gets the first one. A manual traversal of <CODECLASS="literal">@ISA</CODE> is possible, but probably not worth the hassle.</P><PRECLASS="programlisting">my $self = bless {}, $class;for my $class (@ISA) { my $meth = $class . "::_init"; $self->$meth(@_) if $class->can("_init");} </PRE><PCLASS="para">This fragile code assumes that all superclasses initialize their objects with <CODECLASS="literal">_init</CODE> instead of initializing in the constructor. It also assumes that a hash reference is used for the underlying object.<ACLASS="indexterm"NAME="ch13-idx-1000004579-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004579-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000004579-2"></A><ACLASS="indexterm"NAME="ch13-idx-1000004579-3"></A><ACLASS="indexterm"NAME="ch13-idx-1000004579-4"></A><ACLASS="indexterm"NAME="ch13-idx-1000004579-5"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-pgfId-1000006443">See Also</A></H3><PCLASS="para">The discussion on the SUPER class in <ICLASS="filename">perltoot </I>(1) and <ICLASS="filename">perlobj </I>(1), and in the section on "Method Invocation" in <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></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_10.htm"TITLE="13.9. Writing an Inheritable Class"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 13.9. Writing an Inheritable Class"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_12.htm"TITLE="13.11. Generating Attribute Methods Using AUTOLOAD"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 13.11. Generating Attribute Methods Using AUTOLOAD"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">13.9. Writing an Inheritable Class</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.11. Generating Attribute Methods Using AUTOLOAD</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 © 2002</a> O'Reilly & 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 + -