epubjs
Version:
Render ePub documents in the browser, across many devices
86 lines (85 loc) • 11.1 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Visibility of Variables and Methods</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="Visibility of Variables and Methods"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-6-SECT-4"/>Visibility of Variables and Methods</h1></div></div></div><p>One of the most important aspects of object-oriented design is
<span class="emphasis"><em>data hiding</em></span>, or <a id="I_indexterm6_id698819" class="indexterm"/><span class="emphasis"><em>encapsulation</em></span>. By treating an object in
some respects as a “black box” and ignoring the details of its
implementation, we can write more resilient, simpler code with components
that can be easily reused.</p><div class="sect2" title="Basic Access Modifiers"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-4.1"/>Basic Access Modifiers</h2></div></div></div><p><a id="idx10301" class="indexterm"/> <a id="idx10324" class="indexterm"/> <a id="idx10344" class="indexterm"/>By default, the variables and methods of a class are
accessible to members of the class itself and to other classes in the
same package. To borrow from C++ terminology, classes in the same
package are <span class="emphasis"><em>friendly</em></span>. We’ll call this the default
level of visibility. As you’ll see as we go on, the default visibility
lies in the middle of the range of restrictiveness that can be
specified.</p><p>The modifiers <a id="I_indexterm6_id698894" class="indexterm"/><code class="literal">public</code> and <a id="I_indexterm6_id698906" class="indexterm"/><code class="literal">private</code>, on the other
hand, define the extremes. As we mentioned earlier, methods and
variables declared as <code class="literal">private</code> are
accessible only within their class. At the other end of the spectrum,
members declared as <code class="literal">public</code> are
accessible from any class in any package, provided the class itself can
be seen. (The class that contains the methods must also be <code class="literal">public</code> to be seen outside of its package, as
we discussed previously.) The <code class="literal">public</code>
members of a class should define its most general functionality—what the
black box is supposed to do.</p><p><a class="xref" href="ch06s04.html#learnjava3-CHP-6-FIG-7" title="Figure 6-7. Private, default, protected, and public visibility">Figure 6-7</a> illustrates the four
simplest levels of visibility, continuing the example from the previous
section. Public members in <code class="literal">TextArea</code>
are accessible from anywhere. Private members are not visible from
outside the class. The default visibility allows access by other classes
in the package.</p><div class="figure"><a id="learnjava3-CHP-6-FIG-7"/><div class="figure-contents"><div class="mediaobject"><a id="I_6_tt326"/><img src="httpatomoreillycomsourceoreillyimages1707625.png" alt="Private, default, protected, and public visibility"/></div></div><p class="title">Figure 6-7. Private, default, protected, and public visibility</p></div><p>The <a id="I_indexterm6_id698981" class="indexterm"/><code class="literal">protected</code> modifier
allows special access permissions for subclasses. Contrary to how it
might sound, <code class="literal">protected</code> is slightly
less restrictive than the default level of accessibility. In addition to
the default access afforded classes in the same package, <code class="literal">protected</code> members are visible to subclasses of
the class, even if they are defined in a different package. If you are a
C++ programmer used to more restrictive meanings, this may rub you the
wrong way.<sup>[<a id="learnjava3-CHP-6-FNOTE-4" href="#ftn.learnjava3-CHP-6-FNOTE-4" class="footnote">18</a>]</sup></p><p><a class="xref" href="ch06s04.html#learnjava3-CHP-6-TABLE-1" title="Table 6-1. Visibility modifiers">Table 6-1</a> summarizes the levels
of visibility available in Java; it runs generally from most to least
restrictive. Methods and variables are always visible within a declaring
class itself, so the table doesn’t address that scope.</p><div class="table"><a id="learnjava3-CHP-6-TABLE-1"/><p class="title">Table 6-1. Visibility modifiers</p><div class="table-contents"><table summary="Visibility modifiers" style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col/><col/></colgroup><thead><tr><th style="text-align: left"><p>Modifier</p></th><th style="text-align: left"><p>Visibility outside the
class</p></th></tr></thead><tbody><tr><td style="text-align: left"><p> <a id="I_indexterm6_id699084" class="indexterm"/> <code class="literal">private</code>
</p></td><td style="text-align: left"><p>None</p></td></tr><tr><td style="text-align: left"><p>No modifier (default)</p></td><td style="text-align: left"><p>Classes in the package</p></td></tr><tr><td style="text-align: left"><p> <code class="literal">protected</code> </p></td><td style="text-align: left"><p>Classes in package and subclasses
inside or outside the package</p></td></tr><tr><td style="text-align: left"><p> <a id="I_indexterm6_id699138" class="indexterm"/> <code class="literal">public</code>
</p></td><td style="text-align: left"><p>All classes<a id="I_indexterm6_id699157" class="indexterm"/><a id="I_indexterm6_id699164" class="indexterm"/><a id="I_indexterm6_id699171" class="indexterm"/></p></td></tr></tbody></table></div></div></div><div class="sect2" title="Subclasses and Visibility"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-4.2"/>Subclasses and Visibility</h2></div></div></div><p><a id="idx10302" class="indexterm"/> <a id="idx10325" class="indexterm"/> <a id="idx10346" class="indexterm"/>Subclasses add two important (but unrelated) complications
to the topic of visibility. First, when you override methods in a
subclass, the overriding method must be at least as visible as the
overridden method. While it is possible to take a <a id="I_indexterm6_id699232" class="indexterm"/><code class="literal">private</code> method and
override it with a <a id="I_indexterm6_id699243" class="indexterm"/><code class="literal">public</code> method in a
subclass, the reverse is not possible; you can’t override a <code class="literal">public</code> method with a <code class="literal">private</code> method. This restriction makes sense
if you recall that subtypes have to be usable as instances of their
supertype (e.g., a <code class="literal">Mammal</code> is a
subclass of <code class="literal">Animal</code> and, therefore,
must be usable as an <code class="literal">Animal</code>). If we
could override a method with a less visible method, we would have a
problem: our <code class="literal">Mammal</code> might not be able
to do all the things an <code class="literal">Animal</code> can.
However, we can reduce the visibility of a variable. In this case, the
variable acts like any other shadowed variable; the two variables are
distinct and can have separate visibilities in different classes.</p><p>The next complication is a bit harder to follow: the <a id="I_indexterm6_id699299" class="indexterm"/><code class="literal">protected</code> variables of
a class are visible to its subclasses, but only through objects of the
subclass’s type or its subtypes. In other words, a subclass can see a
<code class="literal">protected</code> variable of its superclass
as an inherited variable, but it can’t access that same variable via a
reference to the superclass itself. This statement could be confusing
because it might not be obvious that visibility modifiers don’t restrict
access between instances of the same class in the same way that they
restrict access between instances of different classes. Two instances of
the same class can access all of each other’s members,
<span class="emphasis"><em>including private ones</em></span>, as long as they refer to
each other as the correct type. Said another way: two instances of
<code class="literal">Cat</code> can access all of each other’s
variables and methods (including private ones), but a <code class="literal">Cat</code> can’t access a protected member in an
instance of <code class="literal">Animal</code> unless the
compiler can prove that the <code class="literal">Animal</code> is
a <code class="literal">Cat</code>. That is, <code class="literal">Cat</code>s have the special privileges of being an
<code class="literal">Animal</code> only with respect to other
<code class="literal">Cat</code>s, not just any <code class="literal">Animal</code>. If you find this hard to follow, don’t
worry too much. If you run into this as a problem in the real world, you
are probably trying to do something trickier than you should.<a id="I_indexterm6_id699388" class="indexterm"/><a id="I_indexterm6_id699395" class="indexterm"/></p></div><div class="sect2" title="Interfaces and Visibility"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-6-SECT-4.3"/>Interfaces and Visibility</h2></div></div></div><p><a id="I_indexterm6_id699409" class="indexterm"/> <a id="I_indexterm6_id699420" class="indexterm"/> <a id="idx10345" class="indexterm"/>Interfaces behave like classes within packages. An
interface can be declared <a id="I_indexterm6_id699446" class="indexterm"/><code class="literal">public</code> to make it
visible outside its package. Under the default visibility, an interface
is visible only inside its package. Like classes, only one <code class="literal">public</code> interface can be declared in a
compilation unit (file).<a id="I_indexterm6_id699468" class="indexterm"/></p></div><div class="footnotes"><br/><hr/><div class="footnote"><p><sup>[<a id="ftn.learnjava3-CHP-6-FNOTE-4" href="#learnjava3-CHP-6-FNOTE-4" class="para">18</a>] </sup>Early on, the Java language allowed for certain combinations
of modifiers, one of which was <code class="literal">private
protected</code>. The meaning of <code class="literal">private
protected</code> was to limit visibility strictly to subclasses
(and remove package access). This was later deemed confusing and
overly complex. It is no longer supported.</p></div></div></div></body></html>