"Hello, Amigo! We have a fascinating new topic."

"Today is just a day of fascinating topics!"

"Why, thank you!"

"You're welcome."

"Remember when we introduced the ChessItem base class to simplify all the classes for chess pieces?"

"Yes."

"Now imagine that each piece has a method that handles rendering the piece on the screen. You call the method and the piece draws itself at its current coordinates. Would it be helpful to move this method into the base class?"

"Yes." After I've learned about polymorphism, I would be able to call the render method for all of the pieces, regardless of their type. Something like this:"

For example:
class ChessBoard
{
  public void drawAllChessItems()
  {
  //draw them regardless of their type.
  ArrayList <ChessItem> items = new ArrayList<ChessItem>();
  items.add(new King());
  items.add(new Queen());
  items.add(new Bishop());

  //draw them regardless of their type.
  for (ChessItem item: items)
  {
   item.draw();
  }
 }
}

"Well done. Exactly. And what would be done by the draw method of the ChessItem class itself?"

"I don't know. Chess doesn't have such a piece. And that means it has no visual representation."

"Precisely. And it doesn't make sense to create a ChessItem object. There is no such chess piece. It's only an abstraction—a class that we made for convenience. That's how abstraction works in OOP: we moved all the important (shared by all pieces) data and methods into a base class, but we kept their differences in the classes corresponding to specific chess pieces."

Java has a special class type for this: the abstract class. Here are three things to remember about abstract classes.

1) An abstract class can declare methods without implementing them. Such a method is called an abstract method.

For example:
 public abstract class ChessItem
{
 public int x, y; //coordinates
 private int value; //the piece's "value"

 public int getValue() //an ordinary method, returns value
 {
   return value;
 }

 public abstract void draw(); //abstract method. There is no implementation.

}

2) An abstract method is marked with the keyword abstract.

If a class has even one abstract method, then the class is also marked with abstract.

3) You cannot create objects of an abstract class. Code attempting to do so simply won't compile.

Java code Description
ChessItem item = new ChessItem();
item.draw();
This code won't compile.
ChessItem item = new Queen();
item.draw();
But you can do this.

4) If your class inherits an abstract class, you need to override all of the inherited abstract methods, i.e. you have to implement them. Otherwise, your class will also have to be declared abstract. If the class has even one unimplemented method declared directly in the class or inherited from the parent class, then the class is considered abstract.

"But why is all this necessary? Why do we need abstract classes? Isn't it possible to use ordinary classes instead? And instead of abstract methods, can't we just create empty implementations consisting of opening and closing curly brackets?"

"You could. But these restrictions are like the private modifier. We use the private modifier to deliberately block direct access to data, so that other programmers and their classes use our public methods."

The same applies to an abstract class. Whoever wrote the class doesn't want anyone to create instances of the class. On the contrary, the author expects the abstract methods of his or her abstract class to be inherited and overridden.

"I still don't understand why we would want to complicate our lives this way."

"The advantage of this feature is evident in large projects. The more classes you have, the more clearly you need to delineate their roles. You'll see the advantage of doing this, and soon. Everybody has to go through this."