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

📄 tij0050.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 3 页
字号:
“send a message to an object,” the compiler does some undercover
work for you. There’s a secret first argument passed to the method 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and that argument is the handle to the object that&#8217;s being manipulated.
So the two method calls above become something like:
</FONT><P></DIV>

<font color="#990000"><PRE>Banana.f(a,1);
Banana.f(b,2);</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
is internal and you can&#8217;t write these expressions and get the compiler to
accept them, but it gives you an idea of what&#8217;s happening.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Suppose
you&#8217;re inside a method and you&#8217;d like to get the handle to the
current object. Since that handle is passed 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>secretly</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
by the compiler, there&#8217;s no identifier for it. However, for this purpose
there&#8217;s a keyword: 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword &#8211; which can be used only inside a method &#8211; produces the
handle to the object the method has been called for. You can treat this handle
just like any other object handle. Keep in mind that if you&#8217;re calling a
method of your class from within another method of your class, you don&#8217;t
need to use 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this;</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you simply call the method. The current 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle is automatically used for the other method. Thus you can say:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#0000ff">class</font> Apricot {
  <font color="#0000ff">void</font> pick() { <font color="#009900">/* ... */</font> }
  <font color="#0000ff">void</font> pit() { pick(); <font color="#009900">/* ... */</font> }
}</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Inside
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>pit(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
you 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>could</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
say 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this.pick(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
but there&#8217;s no need to. The compiler does it for you automatically. The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword is used only for those special cases in which you need to explicitly
use the handle to the current object. For example, it&#8217;s often used in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>return</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
statements when you want to return the handle to the current object:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Leaf.java</font>
<font color="#009900">// Simple use of the "this" keyword</font>

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Leaf {
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> i = 0;
  Leaf increment() {
    i++;
    <font color="#0000ff">return</font> <font color="#0000ff">this</font>;
  }
  <font color="#0000ff">void</font> print() {
    System.out.println("i = " + i);
  }
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Leaf x = <font color="#0000ff">new</font> Leaf();
    x.increment().increment().increment().print();
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Because
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>increment(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
returns the handle to the current object via the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword, multiple operations can easily be performed on the same object.
</FONT><P></DIV>
<A NAME="Heading145"></A><H4 ALIGN=LEFT>
Calling
constructors from constructors
<P><A NAME="Index289"></A></H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
you write several constructors for a class, there are times when you&#8217;d
like to call one constructor from another to avoid duplicating code. You can do
this using the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword. 
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Normally,
when you say 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
it is in the sense of &#8220;this object&#8221; or &#8220;the current
object,&#8221; and by itself it produces the handle to the current object. In a
constructor, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword takes on a different meaning when you give it an argument list: it
makes an explicit call to the constructor that matches that argument list. Thus
you have a straightforward way to call other constructors:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Flower.java</font>
<font color="#009900">// Calling constructors with "this"</font>

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Flower {
  <font color="#0000ff">private</font> <font color="#0000ff">int</font> petalCount = 0;
  <font color="#0000ff">private</font> String s = <font color="#0000ff">new</font> String("<font color="#0000ff">null</font>");
  Flower(<font color="#0000ff">int</font> petals) {
    petalCount = petals;
    System.out.println(
      "Constructor w/ <font color="#0000ff">int</font> arg only, petalCount= "
      + petalCount);
  }
  Flower(String ss) {
    System.out.println(
      "Constructor w/ String arg only, s=" + ss);
    s = ss;
  }
  Flower(String s, <font color="#0000ff">int</font> petals) {
    <font color="#0000ff">this</font>(petals);
<font color="#009900">//!    this(s); // Can't call two!</font>
    <font color="#0000ff">this</font>.s = s; <font color="#009900">// Another use of "this"</font>
    System.out.println("String &amp; <font color="#0000ff">int</font> args");
  }
  Flower() {
    <font color="#0000ff">this</font>("hi", 47);
    System.out.println(
      "<font color="#0000ff">default</font> constructor (no args)");
  }
  <font color="#0000ff">void</font> print() {
<font color="#009900">//!    this(11); // Not inside non-constructor!</font>
    System.out.println(
      "petalCount = " + petalCount + " s = "+ s);
  }
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Flower x = <font color="#0000ff">new</font> Flower();
    x.print();
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
constructor 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Flower(String
s, int petals)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
shows that, while you can call one constructor using 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
you cannot call two. In addition, the constructor call must be the first thing
you do or you&#8217;ll get a compiler error message.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
example also shows another way you&#8217;ll see 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
used. Since the name of the argument 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>s
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">and
the name of the member data 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>s</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are the same, there&#8217;s an ambiguity. You can resolve it by saying 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this.s</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to refer to the member data. You&#8217;ll often see this form used in Java
code, and it&#8217;s used in numerous places in this book.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>print(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you can see that the compiler won&#8217;t let you call a constructor from
inside any method other than a constructor.
</FONT><P></DIV>
<A NAME="Heading146"></A><H4 ALIGN=LEFT>
The
meaning of static
<P><A NAME="Index290"></A></H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">With
the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">keyword
in mind, you can more fully understand what it means to make a <A NAME="Index291"></A><A NAME="Index292"></A>method
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
It means that there is no 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for that particular method. You cannot call non-
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods from inside 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods
</FONT><A NAME="fnB18" HREF="#fn18">[18]</A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(although the reverse is possible), and you can call a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method for the class itself, without any object. In fact, that&#8217;s
primarily what a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method is for. It&#8217;s as if you&#8217;re creating the equivalent of a
global function (from C). Except global functions are not permitted in Java,
and putting the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method inside a class allows it access to other 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">methods
and to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
fields.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Some
people argue that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods are not object-oriented since they do have the semantics of a global
function; with a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method you don&#8217;t send a message to an object, since there&#8217;s no 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This is probably a fair argument, and if you find yourself using a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>lot</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
of static methods you should probably rethink your strategy. However, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
are pragmatic and there are times when you genuinely need them, so whether or
not they are &#8220;proper OOP&#8221; should be left to the theoreticians.
Indeed, even <A NAME="Index293"></A>Smalltalk
has the equivalent in its &#8220;class methods.&#8221;
</FONT><a name="_Toc375545281"></a><a name="_Toc408018483"></a><P></DIV>
<HR><DIV ALIGN=LEFT><A NAME="fn17" HREF="#fnB17">[17]</A><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
In some of the Java literature from Sun they instead refer to these with the
clumsy but descriptive name &#8220;no-arg constructors.&#8221; The term
&#8220;default constructor&#8221; has been in use for many years and so I will
use that.
</FONT><P></DIV><DIV ALIGN=LEFT><A NAME="fn18" HREF="#fnB18">[18]</A><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
The one case in which this is possible occurs if you pass a handle to an object
into the 
</FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
method. Then, via the handle (which is now effectively 
</FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black"><B>this</B></FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">),
you can call non-
</FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
methods and access non-
</FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
fields. But typically if you want to do something like this you&#8217;ll just
make an ordinary, non-
</FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
method.
</FONT><P></DIV>


<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0049.html">Prev</a> | <a href="tij0051.html">Next</a>
</div>
</body></html>

⌨️ 快捷键说明

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