Controlling Access to Members of a Class

Access level modifiers determine whether other classes can use a particular field or invoke a particular method. There are two levels of access control:

  • At the top level—public, orpackage-private(no explicit modifier).
  • At the member level—public,private,protected, orpackage-private(no explicit modifier).

A class may be declared with the modifierpublic, in which case that class is visible to all classes everywhere. If a class has no modifier (the default, also known aspackage-private), it is visible only within its own package (packages are named groups of related classes — you will learn about them in a later lesson.)

At the member level, you can also use thepublicmodifier or no modifier (package-private) just as with top-level classes, and with the same meaning. For members, there are two additional access modifiers:privateandprotected. Theprivatemodifier specifies that the member can only be accessed in its own class. Theprotectedmodifier specifies that the member can only be accessed within its own package (as withpackage-private) and, in addition, by a subclass of its class in another package.

The following table shows the access to members permitted by each modifier.

Access Levels
Modifier / Class / Package / Subclass / World
public / Y / Y / Y / Y
protected / Y / Y / Y / N
no modifier / Y / Y / N / N
private / Y / N / N / N

The first data column indicates whether the class itself has access to the member defined by the access level. As you can see, a class always has access to its own members. The second column indicates whether classes in the same package as the class (regardless of their parentage) have access to the member. The third column indicates whether subclasses of the class declared outside this package have access to the member. The fourth column indicates whether all classes have access to the member.

public abstract class HttpServlet {

..

protected abstract void doGet(HttpServletRequestreq, HttpServletResponse
resp);

}

public class HttpServer {

HttpServlet s = HttpServlet.getInstance(servlet);

if (s != null) {

ServletInvocation invocation = new ServletInvocation(parameters,out);

s.doGet(invocation,invocation);

}

] / Can an abstract class have a constructor?
If so, how it can be used and for what purposes?

5 Answers

Consider this:
abstractclassProduct{
intmultiplyBy;
publicProduct(intmultiplyBy){
this.multiplyBy=multiplyBy;
}
publicintmutiply(intval){
returnmuliplyBy*val;
}
}
classTimesTwoextendsProduct{
publicTimesTwo(){
super(2);
}
}
classTimesWhatextendsProduct{
publicTimesWhat(int what){
super(what);
}
}
The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a default constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.
NOTE: As there is no default (or no-arg) constructor in the parent abstract class the constructor used in subclasses must be specified.
Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.

Is Constructor Overriding Possible?

What i know is, the compiler writes a default no argument constructor in the byte code. But if we write it ourselves, that constructor is called automatically. Is this phenomena a constructor overriding?

8 Answers

What you describe isn't overriding. If you don't specify a default constructor, the compiler will create a default constructor. If it's a subclass, it will call the default parent constructor(super()), it will also initialize all instance variables to a default value determined by the type's default value(0 for numeric types, false for booleans, or null for objects).
Overriding happens when a subclass has the same name, number/type of parameters, and the same return type as an instance method of the superclass. In this case, the subclass willoverridethe superclass's method.
Constructors are not normal methods and they cannot be "overridden". Saying that a constructor can be overridden would imply that a superclass constructor would be visible and could be called to create an instance of a subclass. This isn't true... a subclass doesn't have any constructors by default (except a no-arg constructorifthe class it extends has one). It has to explicitly declare any other constructors, and those constructors belong to it and not to its superclass, even if they take the same parameters that the superclass constructors take.
The stuff you mention about default no arg constructors is just an aspect of how constructors work and has nothing to do with overriding.
Private constructors:

Private constructors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 / publicclassClassA
{
privateintval;
publicClassA(intval, booleandummy) {
this(val);
}
privateClassA(intval)
{
this.val = val;
}
publicintgetVal()
{
returnval;
}
}
classClassB extendsClassA
{
publicClassB(intval)
{
super(val, true);
}
}

NESTED CLASSES

Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.
Static nested classes are accessed using the enclosing class name:
OuterClass.StaticNestedClass
For example, to create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClassnestedObject=newOuterClass.StaticNestedClass();
Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:
classOuterClass{
...
classInnerClass{
...
}
}
An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass.InnerClassinnerObject=outerObject.newInnerClass();
see:Java Tutorial - Nested Classes
TheJava tutorial says:
Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.
In common parlance, the terms "nested" and "inner" are used interchangeably by most programmers, so I'll just use the term "inner class".
Inner classes can be nestedad infinitum, e.g. class A can contain class B which contains class C which contains class D, etc. However, more than one level of class nesting is rare, as it is generally bad design.
There are three reasons you might create an inner class:
  • organization: sometimes it seems most sensible to sort a class into the namespace of another class, especially when it won't be used in any other context
  • access: inner classes have special access to the variables/fields of their containing classes (precisely which variables/fields depends on the kind of inner class).
  • convenience: having to create a new file for every new type is bothersome, again, especially when the type will only be used in one context
There arefour kinds of inner class in Java. In brief, they are:
  • static inner class: declared as a static member of another class
  • instance inner class: declared as an instance member of another class
  • local inner class: declared inside an instance method of another class
  • anonymous inner class: like a local inner class, but written as an expression which returns a one-off object
In more detail:
static inner classes
Static inner classes are the easiest kind to understand because they have nothing to do with instances of the containing class.
A static inner class is a class declared as a static member of another class. Just like other static members, such a class is really just a hanger on that uses the containing class as its namespace,e.g.the classGoatdeclared as a static member of classRhinoin the packagepizzais known by the namepizza.Rhino.Goat.
package pizza;
publicclassRhino{
...
publicstaticclassGoat{
...
}
}
Frankly, static inner classes are a pretty worthless feature because classes are already divided into namespaces by packages. The only real conceivable reason to create a static inner class is that such a class has access to its containing class's private static members, but I find this to be a pretty lame justification for the static inner class feature to exist.
instance inner classes
An instance inner class is a class declared as an instance member of another class:
package pizza;
publicclassRhino{
publicclassGoat{
...
}
privatevoid jerry(){
Goat g =newGoat();
}
}
Like with a static inner class, the instance inner class is known as qualified by its containing class name,pizza.Rhino.Goat, but inside the containing class, it can be known by its simple name. However, every instance of an instance inner class is tied to a particular instance of its containing class: above, theGoatcreated injerry, is implicitly tied to theRhinoinstancethisinjerry. Otherwise, we make the associatedRhinoinstance explicit when we instantiateGoat:
Rhinorhino=newRhino();
Rhino.Goat goat =rhino.newGoat();
(Notice you refer to the inner type as justGoatin the weirdnewsyntax: Java infers the containing type from therhinopart. And, yesnew rhino.Goat()would have made more sense to me too.)
So what does this gain us? Well, the inner class instance has access to the instance members of the containing class instance. These enclosing instance members are referred to inside the inner classviajust their simple names, notvia*this* (thisin the inner class refers to the inner class instance, not the associated containing class instance):
publicclassRhino{
privateStringbarry;
publicclassGoat{
publicvoidcolin(){
System.out.println(barry);
}
}
}
In the inner class, you can refer tothisof the containing class asRhino.this, and you can usethisto refer to its members,e.g. Rhino.this.barry.
local inner classes
A local inner class is a class declared in the body of a method. Such a class is only known within its containing method, so it can only be instantiated and have its members accessed within its containing method. The gain is that a local inner class instance is tied to and can access the final local variables of its containing method. When the instance uses a final local of its containing method, the variable retains the value it held at the time of the instance's creation, even if the variable has gone out of scope (this is effectively Java's crude, limited version of closures).
Because a local inner class is neither the member of a class or package, it is not declared with an access level. (Be clear, however, that its own members have access levels like in a normal class.)
If a local inner class is declared in an instance method, an instantiation of the inner class is tied to the instance held by the containing method'sthisat the time of the instance's creation, and so the containing class's instance members are accessible like in an instance inner class. A local inner class is instantiated simplyviaits name,e.g.local inner classCatis instantiated asnew Cat(), not new this.Cat() as you might expect.
anonymous inner classes
An anonymous inner class is a syntactically convenient way of writing a local inner class. Most commonly, a local inner class is instantiated at most just once each time its containing method is run. It would be nice, then, if we could combine the local inner class definition and its single instantiation into one convenient syntax form, and it would also be nice if we didn't have to think up a name for the class (the fewer unhelpful names your code contains, the better). An anonymous inner class allows both these things:
new*ParentClassName*(*constructorArgs*){*members*}
This is an expression returning a new instance of an unnamed class which extendsParentClassName. You cannot supply your own constructor; rather, one is implicitly supplied which simply calls the super constructor, so the arguments supplied must fit the super constructor. (If the parent contains multiple constructors, the “simplest” one is called, “simplest” as determined by a rather complex set of rules not worth bothering to learn in detail--just pay attention to what NetBeans or Eclipse tell you.)
Alternatively, you can specify an interface to implement:
new*InterfaceName*(){*members*}
Such a declaration creates a new instance of an unnamed class which extends Object and implementsInterfaceName. Again, you cannot supply your own constructor; in this case, Java implicitly supplies a no-arg, do-nothing constructor (so there will never be constructor arguments in this case).
Even though you can't give an anonymous inner class a constructor, you can still do any setup you want using an initializer block (a {} block placed outside any method).
Be clear that an anonymous inner class is simply a less flexible way of creating a local inner class with one instance. If you want a local inner class which implements multiple interfaces or which implements interfaces while extending some class other thanObjector which specifies its own constructor, you're stuck creating a regular named local inner class.
I don't think the real difference became clear in the above answers.
First to get the terms right:
  • A nested class is a class which is contained in another class at the source code level.
  • It is static if you declare it with thestaticmodifier.
  • A non-static nested class is called inner class. (I stay with non-static nested class.)
Martin's answer is right so far. However, the actual question is: What is the purpose of declaring a nested class static or not?
You usestatic nested classesif you just want to keep your classes together if they belong topically together or if the nested class is exclusively used in the enclosing class. There is no semantic difference between a static nested class and every other class.
Non-static nested classesare a different beast. Similar to anonymous inner classes, such nested classes are actually closures. That means they capture their surrounding scope and their enclosing instance and make that accessible. Perhaps an example will clarify that. See this stub of a Container:
publicclassContainer{
publicclassItem{
Object data;
publicContainergetContainer(){
returnContainer.this;
}
publicItem(Object data){
super();
this.data= data;
}
}
publicstaticItem create(Object data){
// does not compile since no instance of Container is available
returnnewItem(data);
}
publicItemcreateSubItem(Object data){
// compiles, since 'this' Container is available
returnnewItem(data);
}
}
In this case you want to have a reference from a child item to the parent container. Using a non-static nested class, this works without some work. You can access the enclosing instance of Container with the syntaxContainer.this.

Wildcards

Consider the problem of writing a routine that prints out all the elements in a collection. Here's how you might write it in an older version of the language (i.e., a pre-5.0 release):

voidprintCollection(Collection c) {

Iteratori = c.iterator();

for (k = 0; k < c.size(); k++) {

System.out.println(i.next());

}

}

And here is a naive attempt at writing it using generics (and the newforloop syntax):

voidprintCollection(Collection<Object> c) {

for (Object e : c) {

System.out.println(e);

}

}

The problem is that this new version is much less useful than the old one. Whereas the old code could be called with any kind of collection as a parameter, the new code only takesCollection<Object>, which, as we've just demonstrated, isnota supertype of all kinds of collections!

So whatisthe supertype of all kinds of collections? It's writtenCollection<?>(pronounced "collection of unknown"), that is, a collection whose element type matches anything. It's called awildcard typefor obvious reasons. We can write:

voidprintCollection(Collection<?> c) {

for (Object e : c) {

System.out.println(e);

}

}

and now, we can call it with any type of collection. Notice that insideprintCollection(), we can still read elements fromcand give them typeObject. This is always safe, since whatever the actual type of the collection, it does contain objects. It isn't safe to add arbitrary objects to it however:

Collection<?> c = new ArrayList<String>();

c.add(new Object()); // Compile time error

Since we don't know what the element type ofcstands for, we cannot add objects to it. Theadd()method takes arguments of typeE, the element type of the collection. When the actual type parameter is?, it stands for some unknown type. Any parameter we pass toaddwould have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception isnull, which is a member of every type.

On the other hand, given aList<?>, wecancallget()and make use of the result. The result type is an unknown type, but we always know that it is an object. It is therefore safe to assign the result ofget()to a variable of typeObjector pass it as a parameter where the typeObjectis expected.

Bounded Wildcards

Consider a simple drawing application that can draw shapes such as rectangles and circles. To represent these shapes within the program, you could define a class hierarchy such as this:

public abstract class Shape {

public abstract void draw(Canvas c);

}

public class Circle extends Shape {

privateint x, y, radius;

public void draw(Canvas c) {

...

}

}

public class Rectangle extends Shape {

privateint x, y, width, height;

public void draw(Canvas c) {

...

}

}

These classes can be drawn on a canvas:

public class Canvas {

public void draw(Shape s) {

s.draw(this);

}

}

Any drawing will typically contain a number of shapes. Assuming that they are represented as a list, it would be convenient to have a method inCanvasthat draws them all:

public voiddrawAll(List<Shape> shapes) {

for (Shape s: shapes) {

s.draw(this);

}

}

Now, the type rules say thatdrawAll()can only be called on lists of exactlyShape: it cannot, for instance, be called on aList<Circle>. That is unfortunate, since all the method does is read shapes from the list, so it could just as well be called on aList<Circle>. What we really want is for the method to accept a list ofanykind of shape:

public voiddrawAll(List<? extends Shape> shapes) {

...

}

There is a small but very important difference here: we have replaced the typeList<Shape>withList<?extendsShape>. NowdrawAll()will accept lists of any subclass ofShape, so we can now call it on aList<Circle>if we want.