📄 java2.txt
字号:
. . .
}
Book createBook(int numDays, long numPages) {
...
}
}
In this code example, the internal data to the class Writer (the
variables writersBlock, mood, and income and the method
getIdea()) is all private. The only method accessible from
outside the Writer class is the createBook() method.
createBook() is the only thing other objects (editor objects,
perhaps?) can ask the Writer object to do; the other bits of
data are implementation details that may affect how the book is
written, but don't otherwise need to be visible or accessible
from other sources.
The rule of thumb for private protection is that any data or
behavior internal to the class that other classes or subclasses
should not be touching should be private. Judicious use of
private variables and methods is how you limit the functionality
of a class to only those features you want visible outside that
class-as with the example of the pc components. Remember that an
object's primary job is to encapsulate its data-to hide it from
the world's sight and limit its manipulation. Encapsulation
separates design from implementation, minimizes the amount of
information one class needs to know about another to get its job
done, and reduces the extent of the code changes you need to
make if your internal implementation changes. Also, by
separating the public interface from the private implementation,
your class's interface becomes more abstract-that is, more
general purpose and more easily used for other purposes.
Subclasses of your class can override the more abstract behavior
of your public interface with their own private implementations.
In addition to picking and choosing which methods you'll want to
keep private and which will be accessible to others, a general
rule of thumb is that all the instance variables in a class
should be private, and you should create special nonprivate
methods to get or change those variables. You'll learn more
about this rule and why it's important a little later, in the
section "Instance Variable Protection and Accessor Methods."
Public
The diametric opposite of private protection, and the least
restrictive form of protection, is public. A method or variable
that is declared with the public modifier is accessible to the
class in which it's defined, all the subclasses of that class,
all the classes in the package, and any other classes outside
that package, anywhere in the entire universe of Java classes.
Public protection means that your methods and variables are
accessible to other methods anywhere inside or outside the
current class or package.
Indicating that a method or variable is public isn't necessarily
a bad thing. Just as hiding the data that is internal to your
class using private helps encapsulate an object, using public
methods defines precisely what the interface to instances of
your class is. If you expect your classes to be reused by other
programmers in other programs, the methods that they'll be using
to use your class should be public.
In many ways, public protection is very similar to the default
package protection. Both allow methods and variables to be
accessed by other classes in the same package. The difference
occurs when you create packages of classes. Variables and
methods with package protection can be used in classes that
exist in the same package. But if someone imports your class
into his own program from outside your package, those methods
and variables will not be accessible unless they have been
declared public. Once again, you'll learn more about packages
tomorrow.
Public declarations work just like private ones; simply
substitute the word public for private.
Protected
The final form of protection available in Java concerns the
relationship between a class and its present and future
subclasses declared inside or outside a package. These
subclasses are much closer to a particular class than to any
other "outside" classes for the following reasons:
* Subclasses usually "know" more about the internal
implementation of a superclass.
* Subclasses are often written by you or by someone to whom
you've given your source code.
* Subclasses frequently need to modify or enhance the
representation of the data within a parent class.
To support a special level of visibility reserved for subclasses
somewhat less restrictive than private, Java has an intermediate
level of access between package and private called,
appropriately, protected. Protected methods and variables are
accessible to any class inside the package, as they would be if
they were package protected, but those methods and variables are
also available to any subclasses of your class that have been
defined outside your package.
Protected protection means that your methods and variables are
accessible to all classes inside the package, but only to
subclasses outside the package.
Technical Note
In C++, the protected modifier means that only subclasses
can access a method or variable, period. Java's meaning of
protected is slightly different, also allowing any class
inside the package to access those methods and variables.
Why would you need to do this? You may have methods in your
class that are specific to its internal implementation-that is,
not intended to be used by the general public-but that would be
useful to subclasses for their own internal implementations. In
this case, the developer of the subclass-be it you or someone
else-can be trusted to be able to handle calling or overriding
that method.
For example, let's say you had a class called AudioPlayer, which
plays a digital audio file. AudioPlayer has a method called
openSpeaker(), which is an internal method that interacts with
the hardware to prepare the speaker for playing. openSpeaker()
isn't important to anyone outside the AudioPlayer class, so at
first glance you might want to make it private. A snippet of
AudioPlayer might look something like this:
class AudioPlayer {
private boolean openSpeaker(Speaker sp_ {
// implementation details
}
}
This works fine if AudioPlayer isn't going to be subclassed. But
what if you were going to create a class called
StereoAudioPlayer that is a subclass of AudioPlayer? This class
would want access to the openSpeaker() method so that it can
override it and provide stereo-specific speaker initialization.
You still don't want the method generally available to random
objects (and so it shouldn't be public), but you want the
subclass to have access to it-so protected is just the solution.
Technical Note
In versions of Java and the JDK up to 1.0.1, you could use
private and protected together to create yet another form of
protection that would restrict access to methods or
variables solely to subclasses of a given class. As of
1.0.2, this capability has been removed from the language.
A Summary of Protection Forms
The differences between the various protection types can become
very confusing, particularly in the case of protected methods
and variables. Table 15.1, which summarizes exactly what is
allowed where, will help clarify the differences from the least
restrictive (public) to the most restrictive (private) forms of
protection.
Table 15.1. Different protection schemes.
Visibility public protected package private
From the same class yes yes yes yes
From any class in yes yes yes no
the same package
From any class yes no no no
outside the package
From a subclass in yes yes yes no
the same package
From a subclass yes yes no no
outside the same
package
Method Protection and Inheritance
Setting up protections in new classes with new methods is easy;
you make your decisions based on your design and apply the right
modifiers. When you create subclasses and override other
methods, however, you have to take into account the protection
of the original method.
The general rule in Java is that you cannot override a method
and make the new method more private than the original method
(you can, however, make it more public). More specifically, the
following rules for inherited methods are enforced by Java:
* Methods declared public in a superclass must also be public
in all subclasses (this, by the way, is the reason most of
the applet methods are public).
* Methods declared protected in a superclass must either be
protected or public in subclasses; they cannot be private.
* Methods declared private are not inherited and therefore
this rule doesn't apply.
* Methods declared without protection at all (the implicit
package protection) can be declared more private in
subclasses.
Instance Variable Protection and Accessor Methods
A good rule of thumb in object-oriented programming is that
unless an instance variable is constant it should almost
certainly be private. But, I hear you say, if instance variables
are private, how can they be changed from outside the class?
They can't. That's precisely the point. Instead, if you create
special methods that indirectly read or change the value of that
instance variable, you can much better control the interface of
your classes and how those classes behave. You'll learn about
how to do this later in this section.
Why Nonprivate Instance Variables Are a Bad Idea
In most cases, having someone else accessing or changing
instance variables inside your object isn't a good idea. Take,
for example, a class called circle, whose partial definition
looks like this:
class Circle {
int x, y, radius;
Circle(int x, int y, int radius) {
...
}
void draw() {
...
}
}
The Circle class has three instance variables: for the x and y
position of the center point, and of the radius. A constructor
builds the circle from those three values, and the draw() method
draws the circle on the screen. So far, so good, right?
So let's say you have a Circle object created and drawn on the
screen. Then some other object comes along and changes the value
of radius. Now what? Your circle doesn't know that the radius
has changed. It doesn't know to redraw itself to take advantage
of the new size of the circle. Changing the value of an instance
variable doesn't in itself trigger any methods. You have to rely
on the same random object that changed the radius to also call
the draw() method. And that overly complicates the interface of
your class, making it more prone to errors.
Another example of why it's better not to make instance
variables publicly accessible is that it's not possible to
prevent a nonconstant instance variable from being changed. In
other words, you could create a variable that you'd intended to
be read-only, and perhaps your program was well mannered and
didn't go about changing that variable randomly-but because the
variable is there and available someone else may very well
change it without understanding your methodology.
Why Accessor Methods Are a Better Idea
If all your instance variables are private, how do you give
access to them to the outside world? The answer is to write
special methods to read and change that variable (one for
reading the value of the variable, one for changing it) rather
than allowing it to be read and changed directly. These methods
are sometimes called accessor methods, mutator methods (for
changing the variable) or simply getters and setters.
Accessor methods are special methods you implement to indirectly
modify otherwise private instance variables.
Having a method to change a given instance variable means you
can control both the value that variable is set to (to make sure
it's within the boundaries you expect), as well as perform any
other operations that may need to be done if that variable
changes, for example, to redraw the circle.
Having two methods for reading and changing the variable also
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -