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

📄 ch13_01.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
📖 第 1 页 / 共 3 页
字号:
TITLE="Calling Methods Indirectly">Recipe 13.7</A> shows how to make method calls where the method is determined at runtime.</P><PCLASS="para">Most classes provide <EMCLASS="emphasis">constructor</EM><ACLASS="indexterm"NAME="ch13-idx-1000004428-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004428-1"></A> methods, which return new objects. Unlike some object-oriented languages, constructor methods in Perl are not specially named. In fact, you can name them anything you like. C++ programmers have a penchant for calling their constructors in Perl <CODECLASS="literal">new</CODE><ACLASS="indexterm"NAME="ch13-idx-1000004429-0"></A>. We recommend that you name your constructors whatever makes sense in the context of the problem you're solving. For example, constructors in the Tk extension to Perl are named after the widgets they create. A less common approach is to export a function with the same name as the class; see <ACLASS="xref"HREF="ch13_15.htm#ch13-23490"TITLE="Example: Overloaded StrNum Class">"Example: Overloaded StrNum Class</A>" in <ACLASS="xref"HREF="ch13_15.htm"TITLE="Overloading Operators">Recipe 13.14</A> for an example.</P><PCLASS="para">A typical constructor looks like this:</P><PRECLASS="programlisting">sub new {    my $class = shift;    my $self  = {};         # allocate new hash for object    bless($self, $class);    return $self;}</PRE><PCLASS="para">Call the constructor with:</P><PRECLASS="programlisting">$object = Class-&gt;new();</PRE><PCLASS="para">If there isn't any inheritance or other monkey business working behind the scenes, this is effectively the same as:</P><PRECLASS="programlisting">$object = Class::new(&quot;Class&quot;);</PRE><PCLASS="para">The <CODECLASS="literal">new()</CODE> function's first argument here is the class name to bless the new reference into. A constructor should pass that string as the second argument to <CODECLASS="literal">bless()</CODE>.</P><PCLASS="para"><ACLASS="xref"HREF="ch13_02.htm"TITLE="Constructing an Object">Recipe 13.1</A> also talks about functions that return blessed references. Constructors don't have to be class methods, and writing object methods that return new objects have a number of uses, as discussed in <ACLASS="xref"HREF="ch13_07.htm"TITLE="Cloning Objects">Recipe 13.6</A>.</P><PCLASS="para">A <EMCLASS="emphasis">destructor</EM><ACLASS="indexterm"NAME="ch13-idx-1000004430-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004430-1"></A> is a subroutine that runs when an object's referent is garbage collected. Unlike constructors, you have no choice in naming it. You must name your destructor method <CODECLASS="literal">DESTROY</CODE>. This method, if it exists, will be called for all objects immediately prior to memory deallocation. Destructors, described in <ACLASS="xref"HREF="ch13_03.htm"TITLE="Destroying an Object">Recipe 13.2</A>, are optional.</P><PCLASS="para">Some languages syntactically allow the compiler to restrict access to a class's methods. Perl does not  &nbsp;-   it allows code to call any method of an object. The author of a class should document clearly the <EMCLASS="emphasis">public</EM><ACLASS="indexterm"NAME="ch13-idx-1000004431-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004431-1"></A> methods (those which may be used), and the user of a class should avoid undocumented (implicitly <EMCLASS="emphasis">private</EM>) methods.</P><PCLASS="para">Perl doesn't distinguish between methods that can be called on a class (<EMCLASS="emphasis">class methods</EM><ACLASS="indexterm"NAME="ch13-idx-1000004432-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004432-1"></A>) and methods that can be called on an object (<EMCLASS="emphasis">instance methods</EM>). If you want a particular method to be called as a class method only, do something like this:</P><PRECLASS="programlisting">sub class_only_method {    my $class = shift;    die &quot;class method called on object&quot; if ref $class;    # more code here} </PRE><PCLASS="para">If you want to allow a particular method to be called as an instance method only, do something like this:</P><PRECLASS="programlisting">sub instance_only_method {    my $self = shift;    die &quot;instance method called on class&quot; unless ref $self;    # more code here} </PRE><PCLASS="para">If your code calls an undefined method on an object, Perl won't complain at compile time; the program will instead trigger an exception at run time. Likewise, the compiler can't catch situations where you pass a non-prime value to a method expecting a prime number. Methods are just function calls whose package is determined at run time. Like all indirect functions, they have no <ACLASS="indexterm"NAME="ch13-idx-1000004434-0"></A>prototype checking &nbsp;-   because that happens at compile time. Even if method calls were aware of prototypes, in Perl the compiler is unable to automatically check the precise types or ranges of arguments to functions. Perl prototypes are used to <EMCLASS="emphasis">coerce</EM> a function argument's context, not to check ranges. <ACLASS="xref"HREF="ch10_12.htm"TITLE="Prototyping Functions">Recipe 10.11</A> details Perl's strange perspective on prototypes.</P><PCLASS="para">You can prevent Perl from triggering an exception for undefined methods by using the <ACLASS="indexterm"NAME="ch13-idx-1000004588-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004588-1"></A><ACLASS="indexterm"NAME="ch13-idx-1000004588-2"></A>AUTOLOAD mechanism to catch calls to nonexistent methods. We show an application of this in <ACLASS="xref"HREF="ch13_12.htm"TITLE="Generating Attribute Methods Using AUTOLOAD">Recipe 13.11</A>.<ACLASS="indexterm"NAME="ch13-idx-1000004423-0"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-chap13_inheritance_0">Inheritance</A></H3><PCLASS="para"><ACLASS="indexterm"NAME="ch13-idx-1000004436-0"></A><ACLASS="indexterm"NAME="ch13-idx-1000004436-1"></A>Inheritance defines a hierarchy of classes. Calls to methods not defined in a class search this hierarchy for a method of that name. The first method found is used. Inheritance means allowing one class to piggy-back on top of another so you don't have to write the same code again and again. This is a form of software reuse, and therefore related to Laziness, the principal virtue of a programmer.</P><PCLASS="para">Some languages provide special syntax for inheritance. In Perl, each class (package) can put its list of <EMCLASS="emphasis">superclasses</EM><ACLASS="indexterm"NAME="ch13-idx-1000004437-0"></A> (parents in the hierarchy) into the package global (not a <CODECLASS="literal">my</CODE>) variable <CODECLASS="literal">@ISA</CODE><ACLASS="indexterm"NAME="ch13-idx-1000004438-0"></A>. This list is searched at runtime when a call is made to a method not defined in the object's class. If the first package listed in <CODECLASS="literal">@ISA</CODE> doesn't have the method but that package has its own <CODECLASS="literal">@ISA</CODE>, Perl looks first in <EMCLASS="emphasis">that</EM> package's own <CODECLASS="literal">@ISA</CODE>, recursively, before going on.</P><PCLASS="para">If the inheritance search fails, the same check is run again, this time looking for a method named <CODECLASS="literal">AUTOLOAD</CODE>. The lookup sequence for <CODECLASS="literal">$ob-&gt;meth()</CODE>, where <CODECLASS="literal">$ob</CODE> is of class P, is:</P><ULCLASS="itemizedlist"><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch13-pgfId-179"></A>P::meth</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch13-pgfId-181"></A>All packages S in <CODECLASS="literal">@P::ISA</CODE>, recursively, for any <CODECLASS="literal">S::meth()</CODE></P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch13-pgfId-183"></A>UNIVERSAL::meth</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch13-pgfId-185"></A>The <CODECLASS="literal">P::AUTOLOAD</CODE> subroutine</P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch13-pgfId-187"></A>All packages S in <CODECLASS="literal">@P::ISA</CODE>, recursively, for any <CODECLASS="literal">S::AUTOLOAD()</CODE></P></LI><LICLASS="listitem"><PCLASS="para"><ACLASS="listitem"NAME="ch13-pgfId-189"></A>The <CODECLASS="literal">UNIVERSAL::AUTOLOAD</CODE> subroutine</P></LI></UL><PCLASS="para">Most classes have just one item in their <CODECLASS="literal">@ISA</CODE> array, a situation called <EMCLASS="emphasis">single inheritance</EM><ACLASS="indexterm"NAME="ch13-idx-1000004439-0"></A>. Classes with more than one element in <CODECLASS="literal">@ISA</CODE> represent <EMCLASS="emphasis">multiple inheritance</EM><ACLASS="indexterm"NAME="ch13-idx-1000004440-0"></A>. The benefits of multiple inheritance are widely contested, but it is supported by Perl.</P><PCLASS="para"><ACLASS="xref"HREF="ch13_10.htm"TITLE="Writing an Inheritable Class">Recipe 13.9</A> talks about the basics of inheritance and designing a class so it can be easily subclassed. In <ACLASS="xref"HREF="ch13_11.htm"TITLE="Accessing Overridden Methods">Recipe 13.10</A> we show how a subclass can call overridden methods in its superclasses.</P><PCLASS="para">Perl doesn't support inheritance of data values. A class can, but should not, touch another's data directly. This violates the envelope and ruins the abstraction. If you follow the advice in Recipes <ACLASS="xref"HREF="ch13_11.htm"TITLE="Accessing Overridden Methods">Recipe 13.10</A> and <ACLASS="xref"HREF="ch13_13.htm"TITLE="Solving the Data Inheritance Problem">Recipe 13.12</A>, this won't be much of an issue.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch13-chap13_a_0">A Warning on Indirect Object Notation</A></H3><PCLASS="para">The <EMCLASS="emphasis">indirect</EM><A

⌨️ 快捷键说明

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