September 18, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

SJCP Exam Preparation: Top-level and Inner Classes

  • August 2, 2001
  • By Koray Guclu
  • Send Email »
  • More Articles »

Objectives

One of the Sun Certified Java Programmer (SJCP) Exam's objectives is to declare and construct any kind of class, including top-level, nested top-level, and inner classes. You are obviously going to be asked questions about this in the exam. I will elaborate on this exam objective in detail, with the support of examples and code snippets. You will then have a correct understanding of top-level, nested top-level, and inner class concepts and will be able to solve every question that is related to this exam objective.

Koray Guclu

If you have any questions in your mind after studying this document, do not hesitate to drop me an e-mail, and I will try to clarify things as much as I can.

You can read more information about SCJP certification from the SJCP Web page [2] and you can download the .pdf file called Sun Certified Programmer for Java 2 Platform Success Guide [3].

Top-Level Class

Even a simple program needs to be declared as a class, its purpose does not matter. It can be either a "Hello World" program or an applet. In every case, it must have at least a class declaration. We all know this kind of common class. So, how do we name this type of class? The answer is simple. We declare this class at the top of all other program elements. So this kind of class is called a top-level class. This is the formal name for our normal class declarations as shown below.

// A top level class 

public class Point {

// Class body

}

There are some more points to ponder about a top-level class. We have a public access modifier in the previous example, but we can also declare a top-level class with public, abstract, and final modifiers. Top-level classes can only have public, abstract, and final  modifiers, and it is also possible to not define any class modifiers at all. This is called default/package accessibility. Besides that, private, protected, and static modifiers cannot be used when declaring top-level classes. It is an error to declare the same modifier twice; the compiler will throw a Repeated modifier exception.

More than one top-level class can be defined in a Java source file, but there can be at most one public top-level class declaration. The file name must match the name of the public class. The file name can be anything, provided there is not a public class definition. If there is more than one class declaration in a source file, each will be compiled into separate .class files. The following example has more than one source file. It must be divided into separate source files that have at most one public class declaration. The compiler will complain if there are two public classes at the same file.

//Inner class examples with
//Class Modifiers   

//A top level class
public
class Point {}

abstract class Point {}

final class Point {}

class Point {}

//Some variations

public final class Point{}

public abstract class Point{}

//Error conditions

public public class Point{}//ERROR!

private class Point{}//ERROR! 

protected class Point{}//ERROR!

static class Point{}//ERROR!

An abstract class is a class which may have incomplete implementations for its methods, some of the methods can have implementation and some others can be empty method declarations. If an abstract class is going to be subclassed, all of its incomplete method implementations must be implemented in the subclass, or the subclass must be declared as abstract too; otherwise the compiler will complain.

// An abstract class 

abstract class Shape {
    int x,y; 

    abstract void draw();
    void setX(int _x){ x=_x; }
    void setY(int _y){ y=_y; }
}

class Oval extends Shape{
    int r; 

    void draw() {     
     // implementation to         

   
    // draw an oval          
   
    // on the screen         
         }
         
}

class Line extends Shape{
    int l; 

    void draw() {     
     // implementation to         

   
    // draw a line          
   
    // on the screen         
         }
         
}

/*  
An abstract class that extends shape and does not implement all incomplete implementations that is declared at Shape class. 
draw() method is not implemented in here   for that reson this MovingShape class must be abstract otherwise compiler will complain. 
*/

abstract class MovingShape extends Shape{
    int velocity; 

    abtract void move(int velocity);
}
 

A class that is declared with a final modifier cannot be subclassed. If you want your class not to be able to subclassed, use the final modifier.

A class, defined with an abstract modifier cannot be instantiated, because they have incomplete implementations. This type of class needs to be subclassed and have implementation for its incomplete methods before instantiation.

Multiple inheritance is not allowed in Java. A class can be declared to implement multiple interfaces but can only extend at most one class.

// inheritance example   

class Point {
 int x,y;
}

public class Line extends Point{}

// ERROR! Multiple inheritence
// is not allowed in Java. 
// .. extends Point, Line{} is an error 
// it must be either declared as 
// extends Point{} or extends Line{} 
public class Square extends Point, Line{}

// abstract class example

abstract class Shape {
  // incomplete method 
  // implementation
  abstract void draw() ;
}

An interface is the same as an abstract class, but you cannot define any method implementations at all. Abstract classes allow having some method implementations. Method implementations cannot be defined when an interface is concerned. Interfaces are defined with the interface keyword. An interface doesn't need abstract and class keywords. Member variables are implicitly defined as public static final. An abstract class can have a constructor(s), but the constructor(s) must be implemented. An Interface must not have a constructor at all.

public interface class Shape {
  // note that abstract  
  // is not used in here
  void draw() ;
}

QUESTIONS

1. Which of the following are valid top-level class declarations? Assume that each class is declared in different source files.
a) public class XY{}
b) protected class ZA {}
c) public class XX extends A,B {}
d) protected class Z extends Object {}
e) public class XYZ() extends Object {}
f) private class  extends Object {}

2. What is the correct way of defining an abstract method?
a) void abstract myMethod();
b) abstract void myMethod() {};
c) abstract void myMethod{};
d) abstract myMethod();
e
) abstract int myMethod();

3. Which modifier would you use if you do not want your class to be subclassed?
a) private
b) protected
c) no-access modifier
d) final
e
) static

4. Which interface declaration is correct?
a) public interface MyInteface {  interface myMethod();  }
b
) public interface MyInteface {  void myMethod();   }
c
) public interface MyInteface {  void myMethod() {};  }
d
) public interface MyInteface {  abstract myMethod(); 

Nested top-level classes and interfaces (Static nested classes/interfaces)

We have seen top-level classes so far. So what is the difference? The difference is that nested top-level classes are declared within a class. That is to say, nested top-level classes are declared within an enclosing class. Nested top-level classes are always defined with a static keyword. A nested top-level class/interface is defined as a static member of its enclosing class/interface. For this reason, it can be accessed or instantiated without any instance of an enclosing class. Since it is declared static, it can only access static members of enclosing class. Do not confuse nested top-level classes with top-level classes -- they are not the same.

class Outer { // Top-level class

   static class Inner {
                //Nested Top-level class or
                // static nested class
   }
}

Nested top-level classes can not have the same name as the enclosing class; doing so will cause an exception.

class Outer { // Top-level class

   static class Outer { // ERROR!
                //Nested Top-level class or
                // static nested class
   }
}

Since nested top-level classes are declared static, they act like any other static features of a class. The following example illustrates the instantiation of a nested top-level class.

Outer.Inner theInner= new Outer.Inner();

There is no such thing as an inner interface. Because, interfaces are always implicitly static. They are always top-level, not inner. Inner classes cannot have any static modifiers at all.

interface Outer { // Top-level interface

   interface Inner {// top-level nested
                    // interface 

   }
}

class Outer
class Inner { 

/* This will cause an error. Becuase, you can not define a static modifier inside an inner
class. Inner is an inner class and

InnerInterface
is implicitly static.
Compiler will complain. */ 

   interface InnerInterface {//ERROR!
   }
}

 

Inner Classes

Declaration of a class within another class is called an inner class. It is basically a name for nested classes. A top-level class can be accessed directly without an instance of an enclosing class, but an inner class requires an instance of an outer class. We have used the static modifier when defining a top-level class. If a static modifier is used, there is no requirement for an enclosing class, like a top-level class. For that reason, you can think every type of inner class as a non-static class.

The compiler will throw an error if you want to declare static initializers, because inner classes do not allow static initializer code blocks. Inner classes can have any access modifier, like public, protected, and private, or no access modifier, but it cannot have any static members. An inner class can extend or implement any class or interface, there are no restrictions or obligations. There are three types of inner classes.

  • Member Classes (Non-static inner classes)
  • Local Classes
  • Anonymous Classes

"An inner class is a nested class that is not explicitly or implicitly declared static." ('8.1.2) [1].

Member Classes (Non-static Inner Classes)

A member class is declared as a member of an enclosing class. A member class is declared like a top-level inner class except for a static modifier. Member classes do not have static modifiers.

class Outer { // Top-level class

   class Inner {// without static modifier 
                // Member or Non-static inner
                // class
   }
}

Member classes require an instance of an enclosing class and every instance of a member class holds an implicit reference to its enclosing class. The following example illustrates the instantiation of a member class.

Outer.Inner theInner = new Outer().new Inner();
//or
Outer
theOuter = new Outer();
Outer.Inner theInner = theOuter.new Inner();

Member classes cannot have any static member unless it is a compile-time constant.

"Inner classes may not declare static members, unless they are compile-time constant fields ." ('8.1.2) [1].

The following first code snippet will throw an error, but the second and third code snippets works fine.

//First code snippet with a static member.
class Outer1 { // Top-level class

   class Inner1 {// without static modifier 
                // Member or Non-static inner
                // class
                static int x; // ERROR!
   }
}

//Second code snippet without a static member.
class Outer2 { // Top-level class

   class Inner2 {// without static modifier 
                // Member or Non-static inner
                // class
               int x; // OK!
   }
}

//Third code snippet with a compile-time
// constant

class Outer3 { // Top-level class

   class Inner3 {// without static modifier 
                // Member or Non-static inner class.
                // compile-time constant
               static final int x = 0; // OK!
   }
}

A member class can access all the fields and methods (even private) of an enclosing class. A member class can be declared as public, protected, private, abstract, final, or static. Note that when you declare a member class with a static modifier it will not be an inner class anymore. It will be a top-level nested class.

Local Classes

A local class is declared inside a method, a constructor, a static initializer, or an instance initializer. A local class cannot have a static modifier. A local class is analogous to a local variable in some ways. You cannot use public, protected, private, or static modifiers in a local class analogous to a local variable.

class Outer { // Top-level class

   void method() { // Method declaration
      class Inner {// Local class 
      }
     }
}

A local class can access all the fields and methods of the enclosing class but can only access final modifiers declared inside a method.

class Outer { // Top-level class

   private int cx=0;
   int cy=0;
   void method(int arg,final int fv) {
      int x=0;
      final int y=0;
      class Inner {// Local class 
         //Error! Try to access
         //non-final methods of the class
         System.out.println(arg);//Error!
         System.out.println(x);//Error!
         //Ok!
         System.out.println(cx);//Ok!
         System.out.println(cy);//Ok!
         System.out.println(fv);//Ok!
         System.out.println(y);//Ok!
      }
     }
}

A local class cannot be accessed from outside the method. Local classes cannot be declared as static, but they can be defined in a static context (for example, in a static method).

class Outer { // Top-level class

   void method() { // Method declaration 
      //ERROR! Can not use static modifier
      static class Inner {// ERROR! 
      }
     }
}

//example with static method
class Outer { // Top-level class

   static void method() { // Method declaration
      //OK!
      class Inner {// Local class 
      }
     }
}

Anonymous Classes

An anonymous class is one declared without a name. This is a convenient solution for most situations. You can create an object on the fly this way. For example, event listeners can be created by the use of anonymous inner classes. Anonymous classes do not allow the use of extends and implements clauses and access modifiers. An anonymous class doesn't have constructors, and it is not allowed to define a constructor. Since anonymous classes don't have names, there is no way to define a constructor.

//...
   void initUserInterface() { // Method                                     //declaration
      //... 
      addWindowListener(//Method begins 
                  //class delaration 
                  new WindowAdapter(){  
                         //implemetion for the method 
                      public windowClosing(WindowEvent e)             {  
                              System.exit(0);  
                         }  
                  }  
            );//Method ends 
      //... 
      }
     }
//...

Anonymous classes can either implement an interface or extend a class but cannot do both. The general form is:

//interface implementation
 new InterfaceName() {}
//extends a class
 new ClassName() {} 

The interface name is the name of the interface that is going to be implemented, and the class name is the name of the class that is going to be extended. They are not the name of our newly created class. It is the name of the class that we intend to implement or extend.

QUESTIONS

1.Which variables may be referenced correctly at line 8?
1. public class Outer{
2.     private int a = 0;
3.     public int b = 0;
4.     public void method(final int c) {
5.          int d = 1;
6.             class Inner{
7.                private void innerMethod( int e) {
8.                   //HERE
9.                }
10.           }
11.       }
12. }

2.Which variables may be referenced correctly at line 6?
1. public class Outer{
2.     private int a = 0;
3.     static public int b = 0;
4.     static  class Inner{
5.                private void innerMethod( int e) {
6.                   //HERE
7.                }
8.           }
9.  }

Reference Card

 

Top level nested class

Non static inner class

Local class

Anonymous class

Declaration Context

As static class member

As non-static class member

In block with non-static context

In block with non-static context

Accessibility Modifiers

All

All

None

None

Outer instance

No

Yes

Yes

Yes

Direct Access to enclosing context

Static members in enclosing context

All members in enclosing context

All members in enclosing context + local final variables

All members in enclosing context + local final variables

Defines static or non-static members

Both static and non-static

Only non-static

Only non-static

Only non-static

Constructors

Yes

Yes

Yes

No

Can use extends or implements clauses?

Yes

Yes

Yes

No

 

References

1. Java Language Specification (Second Edition) by James Gosling, Bill Joy, Guy Steele

2. Information about SCJP Certification

3. Sun Certified Programmer for Java 2 Platform Success Guide

About the Author

Koray Guclu works as a freelance writer and instructor. You can reach him at korayguclu@yahoo.com. His Web site is http://www.geocities.com/korayguclu/.






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel