The "abstract" keyword - Abstract classes & Methods
Overview
We'll look at abstract keyword and see why we need it.
Introduction
Consider the following class design:
Figure 1: Vehicle design
We can notice that we are using inheritance in this class design to avoid code duplicity. We also notice that we areoverriding
some methods in TwoWheeler class & FourWheeler class; we also override
some methods in Bicycle, Scooter, Hatchback, SUV, Sedan classes respectively. We can create an object of say class Sedan
like the following:
We can also change the type of our reference variable to any of the superclass of Sedan
, making use of Subtyping polymorphism (read more here). So something like the following is also completely valid:
1/*
2Both of the following statements are completely valid
3because FourWheeler & Vehicle are superclasses of Sedan class
4*/
5FourWheeler sedan = new Sedan();
6Vehicle sedan = new Sedan();
Let's look at another example of class design:

Figure 2: Shape design
We can see that we have Triangle and Rectangle classes which extends a Shape class. These two subclassesoverride
area() method to give their specific implementations. Triangle will define area() method so that it'll give area of a Triangle and Rectangle class will define area() so that it'll give area of a Rectangle. But what will the area() method of Shape class say, probably nothing: just an empty declaration. Will it make sense to create an object of Shape class?
Sometimes there are classes in our design that are only used to give an overall blueprint for it's subclasses. There's no "real world entity" for such classes and such classes should be avoided from getting instantiated i.e. we should not be able to create an object for such a class. Such classes are only useful when they are extended.
"abstract" class
We can use abstract keyword at class level and declare an abstract class.
Abstract Class cannot be instantiated. We cannot create objects of abstract classes and are only useful when extended.
As discussed above, there might be some classes in our design for which we want to disable instantiation. How to do it? Mark the class with "abstract" keyword. Let's see an example:
1class Helper {
2
3 public static void main(String[] args) {
4
5 //trying to instantiate class A
6 A a = new A();
7 }
8}
Abstract class v/s Concrete Class
Simply put, classes which are not abstract are called concrete classes. Concrete classes are the one for which having a real world object makes sense. In our examples above, it makes sense to have objects of class Triangle and Rectangle, hence these are concrete classes.
Note: As a general practice, leaf-classes in UML diagrams are made concrete. Non-leaf classes are made abstract. Though it's not a generalization.
"abstract" Methods
Like classes we can also mark methods with abstract
keyword. How to create an abstract method? Here's a very simple example:
Few Important points on abstract methods:
-
If a class contains abstract method that class must also be marked abstract. For example:
Something like this will cause compilation error:1//A contains an abstract method so we should mark A as abstract as well. 2abstract class A { 3 4 public abstract void func(); 5}
javaError:1//A is not abstract even though it contain a abstract method, should give error 2class A { 3 4 public abstract void func(); 5}
java -
abstract methods have no body and must end with a semicolon (;). For example:
-
An abstract class can have non-abstract methods as well.
-
Reverse is not true, abstract methods cannot be in non-abstract class (as already seen in point 1). If a class contains abstract methods, the class must be marked abstract as well.
-
If a subclass extends a abstract class, the subclass should override all the abstract methods of the superclass.
1abstract class A { 2 3 public abstract void func(); 4 5 public void foo() { 6 7 System.out.println("inside foo()"); 8 } 9}
java1class B extends A { 2 3 public void func() { 4 5 System.out.println("inside B's func()"); 6 } 7}
javaOutput: Class B overrides func() from class A and everything works fine. But if change class B to something like this: we'll get the following error: stating that we must override abstract methods of our superclass.1class Helper { 2 3 public static void main(String[] args) { 4 5 B b = new B(); 6 b.func(); 7 b.foo(); 8 } 9}
java
Need for abstract methods?
As with abstract classes we understood that they are the classes that have no significance in the real world and that they are just the blueprint for their subclasses.
Abstract methods are just the same. Abstract methods work like a "contract" for subclasses saying that each subclass should definitely override me. Consider the following design again:
Figure 3: Shape design
Triangle and Rectangle both override area() method. But what if in Rectangle class we forgot to override area()? To avoid such a thing and to be sure that every subclass of Shape must have it's own implementation of area() method, we can declare area() in Shape as a abstract method. By doing this compiler will ensure that each subclass of Shape will override area() method.Let's think why
- Why do you think abstract methods cannot have a body?
- Why do you think classes with abstract methods should also be marked abstract? Write your answers in comments and let's see if you get these right
Takeaways
- Use of abstract classes and abstract methods
- abstract keyword
Acknowledgements
- Head First Java (2nd Edition)
- Java The Complete Reference (9th Edition)