UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

196 lines (194 loc) 23.9 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <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>