epubjs
Version:
Render ePub documents in the browser, across many devices
196 lines (194 loc) • 23.9 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Classes</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Classes"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-5-SECT-1"/>Classes</h1></div></div></div><p>Classes are the building blocks of a Java application. A
<span class="emphasis"><em>class</em></span> can contain methods (functions), variables,
initialization code, and, as we’ll discuss later, other classes. It serves
as a blueprint for making class <a id="I_indexterm5_id688601" class="indexterm"/><span class="emphasis"><em>instances</em></span>, which are runtime objects
(individual copies) that implement the class structure. You declare a
class with the <a id="I_indexterm5_id688611" class="indexterm"/><code class="literal">class</code> keyword. Methods
and variables of the class appear inside the braces of the class
declaration:</p><a id="I_5_tt223"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="kt">float</code> <code class="n">mass</code><code class="o">;</code>
<code class="kt">float</code> <code class="n">length</code> <code class="o">=</code> <code class="mf">1.0f</code><code class="o">;</code>
<code class="kt">int</code> <code class="n">cycles</code><code class="o">;</code>
<code class="kt">float</code> <code class="nf">getPosition</code> <code class="o">(</code> <code class="kt">float</code> <code class="n">time</code> <code class="o">)</code> <code class="o">{</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>The <code class="literal">Pendulum</code> class contains three
variables: <code class="literal">mass</code>, <code class="literal">length</code>, and <code class="literal">cycles</code>. It also defines a method called <code class="literal">getPosition()</code>, which takes a <code class="literal">float</code> value as an argument and returns a
<code class="literal">float</code> value as a result. Variables and
method declarations can appear in any order, but variable initializers
can’t make “forward references” to other variables that appear later. Once
we’ve defined the <code class="literal">Pendulum</code> class, we
can create a <code class="literal">Pendulum</code> object (an instance of that
class) as follows:</p><a id="I_5_tt224"/><pre class="programlisting"> <code class="n">Pendulum</code> <code class="n">p</code><code class="o">;</code>
<code class="n">p</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Pendulum</code><code class="o">();</code></pre><p>Recall that our declaration of the variable <code class="literal">p</code> doesn’t create a <code class="literal">Pendulum</code> object; it simply creates a variable
that refers to an object of type <code class="literal">Pendulum</code>. We still had to create the object,
using the <a id="I_indexterm5_id688720" class="indexterm"/><code class="literal">new</code> keyword, as shown in
the second line of the preceding code snippet. Now that we’ve created a
<code class="literal">Pendulum</code> object, we can access its
variables and methods, as we’ve already seen many times:</p><a id="I_5_tt225"/><pre class="programlisting"> <code class="n">p</code><code class="o">.</code><code class="na">mass</code> <code class="o">=</code> <code class="mf">5.0</code><code class="o">;</code>
<code class="kt">float</code> <code class="n">pos</code> <code class="o">=</code> <code class="n">p</code><code class="o">.</code><code class="na">getPosition</code><code class="o">(</code> <code class="mf">1.0</code> <code class="o">);</code></pre><p><a id="I_indexterm5_id688751" class="indexterm"/> <a id="I_indexterm5_id688758" class="indexterm"/>Two kinds of variables can be defined in a class:
<span class="emphasis"><em>instance variables</em></span> and <span class="emphasis"><em>static
variables</em></span>. Every object instance has its own set of instance
variables; the values of these variables in one instance of an object can
differ from the values in another object. We’ll talk about static
variables later, which, in contrast, are shared among all instances of an
object. In either case, if you don’t initialize a variable when you
declare it, it’s given a default value appropriate for its type (<code class="literal">null</code>, zero, or <code class="literal">false</code>).</p><p><a class="xref" href="ch05s01.html#learnjava3-CHP-5-FIG-1" title="Figure 5-1. Instances of the Pendulum class">Figure 5-1</a> shows a hypothetical
<code class="literal">TextBook</code> application that uses two
instances of <code class="literal">Pendulum</code> through the
reference-type variables <code class="literal">bigPendulum</code>
and <code class="literal">smallPendulum</code>. Each of these
<code class="literal">Pendulum</code> objects has its own copy of
<code class="literal">mass</code>, <code class="literal">length</code>, and <code class="literal">cycles</code>. As with variables, methods defined in a
class may be <span class="emphasis"><em>instance methods</em></span> or <span class="emphasis"><em>static
methods</em></span>. An instance method is associated with just one
instance of the class, but the relationship isn’t quite as simple as it is
for variables. Instance methods are accessed through an object instance,
but the object doesn’t really have its own “copy” of the methods (there is
no duplication of code). Instead, the association means that instance
methods can “see” and operate on the values of the instance variables of
the object. As you’ll see in <a class="xref" href="ch06.html" title="Chapter 6. Relationships Among Classes">Chapter 6</a> when we
talk about subclassing, there’s more to learn about how methods see
variables. In that chapter, we’ll also discuss how instance methods can be
“overridden” in child classes—a very important feature of object-oriented
design. Both aspects differ from static methods, which we’ll see are
really more like global functions, as they are associated with a class by
name only.</p><div class="sect2" title="Accessing Fields and Methods"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-1.1"/>Accessing Fields and Methods</h2></div></div></div><p><a id="idx10222" class="indexterm"/> <a id="idx10237" class="indexterm"/>Inside a class, we can access variables and call methods
of the class directly by name. Here’s an example that expands on our
<code class="literal">Pendulum</code>:</p><a id="I_5_tt226"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kt">void</code> <code class="nf">resetEverything</code><code class="o">()</code> <code class="o">{</code>
<code class="n">mass</code> <code class="o">=</code> <code class="mf">1.0</code><code class="o">;</code>
<code class="n">length</code> <code class="o">=</code> <code class="mf">1.0</code><code class="o">;</code>
<code class="n">cycles</code> <code class="o">=</code> <code class="mi">0</code><code class="o">;</code>
<code class="o">...</code>
<code class="kt">float</code> <code class="n">startingPosition</code> <code class="o">=</code> <code class="n">getPosition</code><code class="o">(</code> <code class="mf">0.0</code> <code class="o">);</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><div class="figure"><a id="learnjava3-CHP-5-FIG-1"/><div class="figure-contents"><div class="mediaobject"><a id="I_5_tt227"/><img src="httpatomoreillycomsourceoreillyimages1707617.png" alt="Instances of the Pendulum class"/></div></div><p class="title">Figure 5-1. Instances of the Pendulum class</p></div><p>Other classes access members of an object through a reference,
using the dot selector notation that we discussed in the last
chapter:</p><a id="I_5_tt228"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">TextBook</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kt">void</code> <code class="nf">showPendulum</code><code class="o">()</code> <code class="o">{</code>
<code class="n">Pendulum</code> <code class="n">bob</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Pendulum</code><code class="o">();</code>
<code class="o">...</code>
<code class="kt">int</code> <code class="n">i</code> <code class="o">=</code> <code class="n">bob</code><code class="o">.</code><code class="na">cycles</code><code class="o">;</code>
<code class="n">bob</code><code class="o">.</code><code class="na">resetEverything</code><code class="o">();</code>
<code class="n">bob</code><code class="o">.</code><code class="na">mass</code> <code class="o">=</code> <code class="mf">1.01</code><code class="o">;</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>Here we have created a second class, <code class="literal">TextBook</code>, that uses a <code class="literal">Pendulum</code> object. It creates an instance in
<code class="literal">showPendulum()</code> and then invokes
methods and accesses variables of the object through the reference
<code class="literal">bob</code>.</p><p>Several factors affect whether class members can be accessed from
another class. You can use the visibility modifiers <a id="I_indexterm5_id688977" class="indexterm"/><code class="literal">public</code>, <a id="I_indexterm5_id688988" class="indexterm"/><code class="literal">private</code>, and <a id="I_indexterm5_id688998" class="indexterm"/><code class="literal">protected</code> to control
access; classes can also be placed into a <span class="emphasis"><em>package</em></span>,
which affects their scope. The <code class="literal">private</code> modifier, for example, designates a
variable or method for use only by other members of the class itself. In
the previous example, we could change the declaration of our variable
<code class="literal">cycles</code> to <code class="literal">private</code>:</p><a id="I_5_tt229"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kd">private</code> <code class="kt">int</code> <code class="n">cycles</code><code class="o">;</code>
<code class="o">...</code></pre><p>Now we can’t access <code class="literal">cycles</code> from
<code class="literal">TextBook</code>:</p><a id="I_5_tt230"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">TextBook</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kt">void</code> <code class="nf">showPendulum</code><code class="o">()</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kt">int</code> <code class="n">i</code> <code class="o">=</code> <code class="n">bob</code><code class="o">.</code><code class="na">cycles</code><code class="o">;</code> <code class="c1">// Compile-time error</code></pre><p>If we still need to access <code class="literal">cycles</code> in some capacity, we might add a public
<code class="literal">getCycles()</code> method to the <code class="literal">Pendulum</code> class. (Creating accessor methods
like this is a good design rule because it allows future flexibility in
changing the type or behavior of the value.) We’ll take a detailed look
at packages, access modifiers, and how they affect the visibility of
variables and methods in <a class="xref" href="ch06.html" title="Chapter 6. Relationships Among Classes">Chapter 6</a>.<a id="I_indexterm5_id689090" class="indexterm"/><a id="I_indexterm5_id689097" class="indexterm"/></p></div><div class="sect2" title="Static Members"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-5-SECT-1.2"/>Static Members</h2></div></div></div><p><a id="idx10223" class="indexterm"/> <a id="idx10238" class="indexterm"/>As we’ve said, instance variables and methods are
associated with and accessed through an instance of the class (i.e.,
through a particular object, like <code class="literal">bob</code>
in the previous example). In contrast, members that are declared with
the <a id="idx10260" class="indexterm"/><code class="literal">static</code> modifier live in
the class and are shared by all instances of the class. Variables
declared with the <code class="literal">static</code> modifier are
called <span class="emphasis"><em>static variables</em></span> or <span class="emphasis"><em>class
variables</em></span>; similarly, these kinds of methods are called
<span class="emphasis"><em>static methods</em></span> or <span class="emphasis"><em>class
methods</em></span>. We can add a static variable to our <code class="literal">Pendulum</code> example:</p><a id="I_5_tt231"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kd">static</code> <code class="kt">float</code> <code class="n">gravAccel</code> <code class="o">=</code> <code class="mf">9.80</code><code class="o">;</code>
<code class="o">...</code></pre><p>We have declared the new <code class="literal">float</code>
variable <code class="literal">gravAccel</code> as <code class="literal">static</code>. That means that it is associated with
the class, not with an individual instance and if we change its value
(either directly or through any instance of a <code class="literal">Pendulum</code>), the value changes for all <code class="literal">Pendulum</code> objects, as shown in <a class="xref" href="ch05s01.html#learnjava3-CHP-5-FIG-2" title="Figure 5-2. Static variables shared by all instances of a class">Figure 5-2</a>.</p><div class="figure"><a id="learnjava3-CHP-5-FIG-2"/><div class="figure-contents"><div class="mediaobject"><a id="I_5_tt234"/><img src="httpatomoreillycomsourceoreillyimages1707618.png" alt="Static variables shared by all instances of a class"/></div></div><p class="title">Figure 5-2. Static variables shared by all instances of a class</p></div><p>Static members can be accessed like instance members. Inside our
<code class="literal">Pendulum</code> class, we can refer to
<code class="literal">gravAccel</code> like any other
variable:</p><a id="I_5_tt232"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kt">float</code> <code class="nf">getWeight</code> <code class="o">()</code> <code class="o">{</code>
<code class="k">return</code> <code class="n">mass</code> <code class="o">*</code> <code class="n">gravAccel</code><code class="o">;</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><p>However, since static members exist in the class itself,
independent of any instance, we can also access them directly through
the class. We don’t need a <code class="literal">Pendulum</code>
object to get or set the variable <code class="literal">gravAccel</code>; instead, we can use the class to
select the variable:</p><a id="I_5_tt233"/><pre class="programlisting"> <code class="n">Pendulum</code><code class="o">.</code><code class="na">gravAccel</code> <code class="o">=</code> <code class="mf">8.76</code><code class="o">;</code></pre><p>This changes the value of <code class="literal">gravAccel</code> as seen by all instances. Why would
we want to change the value of <code class="literal">gravAccel</code>? Well, perhaps we want to explore
how pendulums would work on different planets. Static variables are also
very useful for other kinds of data that is shared among classes at
runtime. For instance, you can create methods to register your object
instances so that they can communicate, or so that you can keep track of
all of them. It’s also common to use static variables to define constant
values. In this case, we use the <code class="literal">static</code> modifier along with the <a id="I_indexterm5_id689327" class="indexterm"/><code class="literal">final</code> modifier. So, if
we cared only about pendulums under the influence of the Earth’s
gravitational pull, we might change <code class="literal">Pendulum</code> as follows:</p><a id="I_5_tt235"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kd">static</code> <code class="kd">final</code> <code class="kt">float</code> <code class="n">EARTH_G</code> <code class="o">=</code> <code class="mf">9.80</code><code class="o">;</code>
<code class="o">...</code></pre><p>We have followed a common convention here and named our constant
with capital letters. The value of <code class="literal">EARTH_G</code> is a constant; it can be accessed
through the class <code class="literal">Pendulum</code> or its
instances, but its value can’t be changed at runtime.</p><p>It’s important to use the combination of <a id="I_indexterm5_id689372" class="indexterm"/><code class="literal">static</code> and <a id="I_indexterm5_id689384" class="indexterm"/><code class="literal">final</code> only for things
that are really constant. That’s because the compiler is allowed to
“inline” such values within classes that reference them. This means that
if you change a <code class="literal">static final</code>
variable, you may have to recompile all code that uses that class (this
is really the only case where you have to do that in Java). Static
members are useful as flags and identifiers, which can be accessed from
anywhere. They are also useful for values needed in the construction of
an instance itself. In our example, we might declare a number of static
values to represent various kinds of <code class="literal">Pendulum</code> objects:</p><a id="I_5_tt236"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kd">static</code> <code class="kt">int</code> <code class="n">SIMPLE</code> <code class="o">=</code> <code class="mi">0</code><code class="o">,</code> <code class="n">ONE_SPRING</code> <code class="o">=</code> <code class="mi">1</code><code class="o">,</code> <code class="n">TWO_SPRING</code> <code class="o">=</code> <code class="mi">2</code><code class="o">;</code>
<code class="o">...</code></pre><p>We might then use these flags in a method that sets the type of a
<code class="literal">Pendulum</code> or in a special constructor,
as we’ll discuss shortly:</p><a id="I_5_tt237"/><pre class="programlisting"> <code class="n">Pendulum</code> <code class="n">pendy</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Pendulum</code><code class="o">();</code>
<code class="n">pendy</code><code class="o">.</code><code class="na">setType</code><code class="o">(</code> <code class="n">Pendulum</code><code class="o">.</code><code class="na">ONE_SPRING</code> <code class="o">);</code></pre><p>Again, inside the <code class="literal">Pendulum</code>
class, we can use static members directly by name, as well; there’s no
need for the <code class="literal">Pendulum.</code> prefix:</p><a id="I_5_tt238"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">Pendulum</code> <code class="o">{</code>
<code class="o">...</code>
<code class="kt">void</code> <code class="nf">resetEverything</code><code class="o">()</code> <code class="o">{</code>
<code class="n">setType</code> <code class="o">(</code> <code class="n">SIMPLE</code> <code class="o">);</code>
<code class="o">...</code>
<code class="o">}</code>
<code class="o">...</code>
<code class="o">}</code></pre><div class="sect3" title="Constants versus enumerations"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-5-SECT-1.2.1"/>Constants versus enumerations</h3></div></div></div><p>In the previous section, we saw two uses for static final
variables (constants). The first was to create true constants; in that
case, it was the numeric constant <code class="literal">EARTH_G</code>, but it could easily have been a
<code class="literal">String</code> or <code class="literal">Date</code> value. The second usage was to create a
fixed set of identifiers, <code class="literal">SIMPLE</code>,
<code class="literal">ONE_SPRING</code>, etc., whose actual
values were not as important as their uniqueness and, perhaps, their
particular order.</p><p><span class="emphasis"><em>Enumerations</em></span> were added to the Java
language to replace this identifier usage with a mechanism that is
both safer and, in some cases, more efficient. We could have declared
our pendulum types as an enumeration like so:</p><a id="I_5_tt239"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">enum</code> <code class="n">PendulumTypes</code> <code class="o">{</code> <code class="n">Simple</code><code class="o">,</code> <code class="n">OneSpring</code><code class="o">,</code> <code class="n">TwoSpring</code> <code class="o">}</code></pre><p>This enumeration creates not only the values, but also a new
type, <code class="literal">PendulumTypes</code>, whose value is
limited to one of the three discrete identifiers. Calling code can
refer to the values as it did through our class: <code class="literal">PendulumTypes.Simple</code>. We’ve changed our case
convention here to diverge from the convention for integer constants,
but you can stick with uppercase if you prefer.</p><p>Later, when we talk about importing classes and packages, we’ll
discuss the <span class="emphasis"><em>static import</em></span> feature of Java, which
allows us to import static identifiers and enumerations (which, as
we’ve seen, are related) into a class so that we can use them by their
simple names. For example:</p><a id="I_5_tt240"/><pre class="programlisting"> <code class="k">new</code> <code class="nf">Pendulum</code><code class="o">(</code><code class="n">OneSpring</code> <code class="o">);</code></pre><p>We’ll go into detail about enumerations later in this chapter
after we’ve covered objects in more depth.<a id="I_indexterm5_id689558" class="indexterm"/><a id="I_indexterm5_id689566" class="indexterm"/></p></div></div></div></body></html>