OCA Java SE 8 Class Design - Java Extend Abstract Class








Creating a Concrete Class

Abstract classes cannot be instantiated.

For example, the following code will not compile as it is an attempt to instantiate an abstract class.

public abstract class Main { 
  public static void main(String[] args) { 
    final Main m = new Main();  // DOES NOT COMPILE 
  } 
} 

An abstract class becomes useful when it is extended by a concrete subclass.

A concrete class is the first nonabstract subclass that extends an abstract class and is required to implement all inherited abstract methods.

Let's review this with the following example.

public abstract class Shape { 
  public abstract String getName(); 
} 

public class Rectangle extends Shape { // DOES NOT COMPILE 
} 

Shape is marked as abstract and Rectangle is not.

In this example, Rectangle is considered the first concrete subclass of Shape.

Rectangle is the first concrete subclass, it must implement all inherited abstract methods, getName() in this example. Because it doesn't, the compiler rejects the code.

For example, the following variation will also not compile:

public abstract class Shape { 
  public abstract String getName(); 
} 

public class P extends Shape { // DOES NOT COMPILE 
} 

public class A extends P { 
  public String getName() { 
    return "A"; 
  } 
} 

Even though a second subclass A implements the abstract method getName(), the first concrete subclass P doesn't; therefore, the P class will not compile.





Extending an Abstract Class

public abstract class Shape { 
  public abstract String getName(); 
} 

public class Rectangle extends Shape { // DOES NOT COMPILE 
} 

public abstract class Rectangle extends Shape { 
} 

In this example, we again have an abstract class Shape with a concrete subclass Rectangle that doesn't compile since it doesn't implement a getName() method.

We also have an abstract class Rectangle, which like Rectangle extends Shape and doesn't provide an implementation for getName().

In this situation, the second Rectangle does compile because it is marked as abstract.

Abstract classes can extend other abstract classes and are not required to provide implementations for any of the abstract methods.

A concrete class that extends an abstract class must implement all inherited abstract methods.

For example, the following concrete class Rectangle must implement two methods, getName() and output():

public abstract class Shape { 
  public abstract String getName(); 
} 

public abstract class Printer extends Shape { 
  public abstract void output(); 
} 

public class Rectangle extends Printer { 
  public String getName() { 
    return "Rectangle"; 
  } 
  public void output() { 
    System.out.println("The Rectangle!"); 
  } 
} 

Printer extends Shape but is marked as abstract; therefore, it is not required to provide an implementation for the getName() method.

The class Rectangle is not marked as abstract, and as the first concrete subclass, it must implement all inherited abstract methods not defined in a parent class.

A concrete subclass is not required to provide an implementation for an abstract method if an intermediate abstract class provides the implementation.





Example

For example, take a look at the following variation on our previous example:

public abstract class Shape { 
  public abstract String getName(); 
} 

public abstract class Printer extends Shape { 
  public String getName() { 
    return "Printer"; 
  } 
  public abstract void output(); 
} 

public class Rectangle extends Printer { 
  public void output() { 
    System.out.println("The Rectangle lets out a loud ROAR!"); 
  } 
} 

Printer provides an implementation for the abstract method getName() defined in the abstract Shape class.

Rectangle inherits only one abstract method, output(), and is not required to provide an implementation for the method getName().

If an intermediate class provides an implementation for an abstract method, that method is inherited by subclasses as a concrete method.

The subclasses do not consider the abstract method an inherited abstract method because it is no longer abstract by the time it reaches the subclasses.

Abstract Class Definition Rules

Abstract classes cannot be instantiated.

Abstract classes may be zero of abstract and non-abstract methods.

Abstract classes cannot be marked as private or final.

An abstract class that extends another abstract class inherits abstract methods from parent as its own abstract methods.

The first concrete class that extends an abstract class must provide an implementation for all of the inherited abstract methods.

Abstract Method Definition Rules

Abstract methods may only be defined within abstract classes.

Abstract methods may not be declared private or final.

Abstract methods must not provide a method body/implementation in the abstract class for which is it declared.