The Artima Developer Community
Sponsored Link

Legacy Java Answers Forum
July 2000

Advertisement

Advertisement

This page contains an archived post to the Java Answers Forum made prior to February 25, 2002. If you wish to participate in discussions, please visit the new Artima Forums.

Message:

Access Modifier Musings...

Posted by Isa Leshko on July 04, 2000 at 12:53 PM

Hi Erik,

I agree that that working with access modifiers can be a bit
tricky, particularly to those new to Java.

Let me first briefly summarize the differences between public,
private, "friendly" (package) and protected access modifiers.
Think of these modifiers as a means of controling access
of particular features of a given class. Class features include:

o the class itself
o its class variables
o its methods and constructors

Note that only class-level variables can and should be
controlled by access modifiers. This idea makes sense, actually,
when you remember that variables local to a method can only
be used within that method.

OK, so now the summary of the modifers. Liberally snipped from
"The Complete Java 2 Certification Study Guide" by Simon Roberts,
Philip Heller, and Michael Ernest. These modifers below
are ordered from least to most restrictive.

o public:
A public feature may be access by any class at all.
For example, applets are declared public so they
may be instantiated by browsers.

o protected:
This name is somewhat confusing, since it implies a
fairly restrictive level of access. The reality is that
protective features are more accessible than so-called
friendly or private features.

A protected feature may only be accessed by a subclass
of the class that owns the feature, or by a member of
the same package as the class that owns the feature.

For more information on packages, see the "Creating and
Using Packages" from the Sun Java Tutorial:
http://java.sun.com/docs/books/tutorial/java/interpack/packages.html

o friendly (aka package)
Friendly or package-level access is the default level
when no other modifier is specified. A friendly feature
may be access by any class residing in the same package
as the class that owns the feature. Classes outside the
package may not access a friendly feature. Otherwise,
that would be the same level of access as public!

Here's one thing that will make your head hurt. Assume
that we have a Shape class that resides in package
com.cadac.abstract and we have a Rectangle class
that extends Shape, but resides in a different package,
say, com.cadac.concrete.

Even though Rectangle is a subclass of Shape, it cannot
access Shape's friendly members. That is because Shape
resides in a separate package. You would need to make
Shape's members protected (or public) if you wanted to
provide Rectangle access to them.

One additional note about the friendly access modifier.
Many new Java programmers have the tendency to not specify
any modifier (thereby using the friendly) modifier. They
also have a tendency to not venture into using packages,
and instead save all of their code in one directory.

Keep in mind that the Java runtime environment considers
any classes sharing a directory to reside in the same
package. So, if you develop all of your programs in one
directory, and don't specify any access modifers for your
class members, you end up with quite an insecure mess.
All of your classes, regardless of their functionality
can access members of all the other classes in that
directory. It's therefore a good idea to get familiar with
working with packages and access modifiers as soon as
possible. :-)

o private:
This modifer is the most restrictive. A private feature
may only be accessed by the class that owns the feature.

The principle of encapsulation dictates that data members
and other implementation details are hidden from users
of a class.

However, the public interface of a class (i.e., members
accessible to other classes) could include accessor
and/or mutator methods. These public methods allow users
of the class to view or manipulate the value of a private
data member:
// accessor or "getter" method
public void getSomeValue()
{
return someValue;
}

// mutator or "setter" method
public int setSomeValue(int someValue)
{
// error checking can go here!
this.someValue = someValue;
}

Yes, having to write all of these extra methods can be
tedious. But you gain significant benefits:

o You can modify the internal implementation of your
class without affecting other classes that use
this class;
o You can add error checking into mutator methods;
o It's also easier to detect and resolve bugs if
you consistently manipulate a data member using
a mutator method.

Now, to answer your specific question:
> It is this idea that a class derived from
>another class ('extends') does not inherit private members
>from the base class.

Actually, it *does* inherit these members. A subclass inherits
all of the functionality of its parent class. Nonetheless,
it cannot access or manipuate private members of its parent
even though it technically "owns" them too.

Other fine print involving the private modifer:
o Top-level classes cannot be declared private.
o Any instance of a given class can access private members
of another instance of that class. The following code
snippet from "The Complete Java 2 Certification Study
Guide" illustrates this point well:

class Complex
{
private double real, imaginary;

public Complex(double r, double i)
{
real = r;
imaginary = i;
}

public Complex add(Complex c)
{
// note that it's perfectly legal for
// this method to access real and imaginary
// belonging to another instance of Complex
// even though these data members are private
double newRealValue = real + c.real;
double newImaginaryValue = imaginary + c.imaginary;
return new Complex(newRealValue, newImaginaryValue);
}
}

class Client
{
void useThem()
{
Complex c1 = new Complex(1, 2);
Complex c2 = new Complex(3, 4);
Complex c3 = c1.add(c2);
// the following line, though, is illegal
// because real is private and Client is
// a distinct class from Complex.
double d = c3.real;
}
}


One additional important point on this topic involves
overriding methods. A subclass is able to define a new
behavior for a method that it inherits from its super/parent
class. For example, the Shape class may have an abstract
method named draw(). Rectangle will inherit this method
when it extends Shape, and it will define its own behavior
for drawing itself, thereby overriding the Shape version
of draw.

When you override a method, you can change its access level
providing that you do not make it more private. For example,
if a parent class has a public method named foo, its child
class can not make foo private. Doing so will generate a
compiler error that says, "Methods cannot be overriden to
be more private."

The following figure from "The Complete Java 2 Certification
Study Guide" summarizes the legal path for overriding
a method with a different access type:

private -> friendly -> protected -> public

For more information on Overriding methods, see the following
chapter from the Sun Java Tutorial:
http://java.sun.com/docs/books/tutorial/java/javaOO/override.html

For more information on the above Access Modifiers, see
the "Controlling Access to Members of a Class" chapter
of the Sun Java Tutorial:
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

Another great resource is the "Encapsulation" chapter
from Lynn Andrea Stein's Intro to Interactive Programming:
http://www-cs101.ai.mit.edu/ipij/procedures.html

This is probably more information than you needed or wanted,
but I had fun writing this message. :-) Seriously, hope
this info helps.

--Isa




Replies:

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us