Advanced Class DesignJ8 Home « Advanced Class Design

Lets take a look at the points outlined at Oracle Java SE 8 Programmer II for this part of the certification.

  • Advanced Java Class Design
    1. Develop code that uses abstract classes and methods.
    2. Develop code that uses the final keyword.
    3. Create inner classes including static inner class, local class, nested class, and anonymous inner class.
    4. Use enumerated types including methods, and constructors in an enum type.
    5. Develop code that declares, implements and/or extends interfaces and use the @Override annotation.
    6. Create and use Lambda expressions.

Abstract ClassesTop

Abstract classes are used when the object in question is too abstract to make a concrete class. We saw an examples of this in the Abstraction lesson when we made the Vehicle and Truck classes abstract and make concrete subclasses such as Car and HGV. Of couse we could have abstracted these subclasses further to actual car and hgv types but that would have over complicated the focus of that lesson. There are a few rules involved when creating abstract classes:

  • Abstract classes can never be instantiated.
  • The whole purpose of an abstract class is to be subclassed, therefore an abstract class can never have a modifier of final.
  • If any method on a class is marked as abstract, then the class must also be marked as abstract.
  • An abstract class can contain abstract and non abstract methods.
  • An abstract class can extend an abstract class.



/*
  Some code showing abstract rules
*/
abstract class A { }           // OK

abstract class B extends A { 
    A a = new A();
}                              // No, you can never instantiate an abstract class

abstract final class C { }     // No, cannot use both abstract and final

class D {
    abstract void methodA(); 
}                              // No, if any method is marked as abstract, the class must be abstract

abstract class E {
    abstract void methodA(); 
}                              // OK

abstract class F {
    abstract void methodA(); 
    void methodB() {} 
}                              // OK, an abstract class can contain abstract and non abstract methods

abstract class G extends F {}  // OK, an abstract class can extend an abstract class

Nested ClassesTop

A nested class is only known to the enclosing class and shares its scope. This means that non-static nested classes have access to all the members and variables of the outer class. Conversely the outer class knows nothing of the internal working of the nested class. The benefits that all nested classes receive are:

  • When a class has a specific purpose that is only relevant to one other class it makes sense to put the helper class within the class that uses it and we can use a nested class for this purpose.
  • Because nested classes have access to all the outer classes members, including members with the private access modifier, it gives us a way to keep outer class members private while still being able to access them, thus increasing encapsulation.
  • Having nested classes allows us to have inner classes close to the top-level classes that enclose them, making code easier to understand and maintain.

Nested classes can be static, which are known as static member classes, or non-static, which are known as inner classes. The lesson on Nested Classes covers instantiation of all types of nested class so we will just cover the guidelines for each type here:

Static Member Classes

A static member class is associated with its outer class in the same way that static members of the outer class would be. This means that a static member class cannot refer to non-static variables and methods defined within the outer class and can only interact with them through an object reference.

Behaviourally, static member classes act like any other top-level class and essentially are top-level classes that have been nested in another top-level class to facilitate packaging, or are associated with the outer class but it makes no sense to attach them to an instance of that class.

Non-static Member Classes

This type of inner class is a member of the outer class just like instance variables and methods are and as such the same modifiers and rules apply as to amy member. We can instantiate a non-static member class as part of the outer class state or seperately when you don't want all outer instances to have an inner instance.

  • Using non-static member classes is very useful when we require a class that doesn't pass the IS-A test but is intrinsicly associated with its enclosing class.
  • A non-static member class is a member of a class just like any other member and as such can have the same modifers applied in its class declaration: these being abstract, final, private, protected, public, static and strictfp.
    • Of course using the static keyword in the class declaration means we have turned the non-static member class into a static member class and so no longer have access to any instance variables and methods.
  • If the class is required by other classes as well, then the class would be better suited as a standard top-level class instead.

Local Inner Classes

Local inner classes can be declared anywhere a local variable can be declared and have the same Method Scope. If you don't require the local inner class to be attached to an instance of the enclosing class, then the nested class should be declared in a static context. Local inner classes cannot contain static members and for readability the coding should be kept to a minimum.

  • The only valid modifers you can apply to a local inner class declaration are final or abstract.
  • Local inner classes can only be instantiated from within the method they are declared in.
  • When instantiating a local inner class, the instantiation code must come after the local inner class declaration.
  • The local inner class can only use final local variables defined within the method it resides in, outside those defined within itself and the outer instance.
  • When creating local inner classes and the code is quite robust, or the code needs to be accessible from more than one method, it is better to make a non-static member class.

Anonymous Inner Classes

The final type of inner classes we can use are anonymous inner classes which are different syntactically from anything else in Java and come with a lot of constraints:

  • Anonymous inner classes as the terminology implies have no name.
  • You can't execute the instanceof test against anonymous inner classes or any process that requires the name of the class.
  • Anonymous inner classes are not members of their enclosing class; in fact they are both declared and instantiated at the point of use.
  • Anonymous inner classes cannot contain any static members
  • Anonymous inner classes can be coded anywhere where an expression is legal, so keep the code to a minimum to maintain readability.
  • Anonymous inner classes can't be declared to extend a class and implement an interface
  • Anonymous inner classes can't implement multiple interfaces.
  • Anonymous inner classes can only invoke members inherited from the supertype

Interface DeclarationTop

In the first part of this lesson we look at interfaces and the contracts we provide when using them. We create an interface using the interface keyword, instead of class in the definition. All interface methods are implicitly declared as public and abstract so there is no need to code these modifiers when creating the interface. Interface methods have no body and end in a semicolon. In fact you can think of an interface as a pure abstract class, which we will talk about below, because every method must be abstract. Lets start with some rules for declaring interfaces:

  • We must adhere to the contract specified in the interface when using it by providing concrete implementations of all methods within the interface.
  • Interface implementations must adhere to the rules for overrides which are discussed in the Working with Inheritance lesson.
  • We can use an abstract class to implement an interface and by doing this defer the contract implementation of the interface to the first concrete subclass of the abstract class.
  • An interface can extend one or more other interfaces, it does not implement them.
  • A class can implement one or more interfaces.
  • A class can extend another class and implement one or more interfaces, but the extend keyword must come first.



/*
  Some code showing interface rules
*/
interface A { }                        // OK
interface B { }                        // OK
interface C { }                        // OK
class D { }                            
class E { }                            
abstract class F { }                   
interface B implements A { }           // No, an interface can't implement another interface
interface B extends A { }              // OK, an interface can extend another interface
interface B implements D { }           // No, an interface can't implement a class
interface B extends C, A { }           // OK, an interface can extend multiple interfaces
class D implements E { }               // No, a class can't implement another class
class D implements A { }               // OK
class D implements A, B { }            // OK, a class can implement one or more interfaces
class E extends D implements A { }     // OK, we can extend a class and implement an interface
class E implements A extends D { }     // No, extend keyword must come first
abstract class F implements A { }      // OK, an abstract class can implement an interface


Related Java Tutorials

Objects & Classes - Reference Variables - The new Operator
Objects & Classes - Constructors
OO Concepts - Encapsulation
OO Concepts - Polymorphism
OO Concepts - Overriding Methods
Objects & Classes - Overloaded Methods
OO Concepts - Accessing Superclass Members
Inheritance Concepts - Superclass Constructors
OO Concepts - Static Overrides?
OO Concepts - IS-A and HAS-A Relationships