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:
We can notice that we are using inheritance in this class design to avoid code duplicity. We also notice that we are overriding
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:
1Sedan sedan = new Sedan();
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();
1Vehicle vehicle = new Vehicle();
Let's look at another example of class design:
We can see that we have Triangle and Rectangle classes which extends a Shape class. These two subclasses
override
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:
1abstract class A {
2
3 public void func() {
4
5 System.out.println("inside func()");
6 }
7}
1class Helper {
2
3 public static void main(String[] args) {
4
5 //trying to instantiate class A
6 A a = new A();
7 }
8}
1Helper.java:6: error: A is abstract; cannot be instantiated
2 A a = new A();
3 ^
41 error
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:
1abstract class A {
2
3 public abstract void func();
4}
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}
Error:1//A is not abstract even though it contain a abstract method, should give error 2class A { 3 4 public abstract void func(); 5}
1./A.java:1: error: A is not abstract and does not override abstract method func() in A 2class A { 3^ 41 error
-
abstract methods have no body and must end with a semicolon (;). For example:
1class A { 2 3 public abstract void func(); //ends with a semicolon 4}
-
An abstract class can have non-abstract methods as well.
1abstract class A { 2 3 public abstract void func(); 4 5 // a non-abstract method in abstract class 6 public void foo() { 7 8 System.out.println("inside foo()"); 9 } 10}
-
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}
1class B extends A { 2 3 public void func() { 4 5 System.out.println("inside B's func()"); 6 } 7}
Output:1class Helper { 2 3 public static void main(String[] args) { 4 5 B b = new B(); 6 b.func(); 7 b.foo(); 8 } 9}
Class B overrides func() from class A and everything works fine. But if change class B to something like this:1inside B's func() 2inside foo()
we'll get the following error:1class B extends A { 2 3}
stating that we must override abstract methods of our superclass.1./B.java:1: error: B is not abstract and does not override abstract method func() in A 2class B extends A { 3^ 41 error
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:
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)