Skip to content
thesarfo

Concept

Abstract Classes

What an abstract class is, why you'd use one, and worked examples including a comparison against interfaces.

views 0

An abstract class is a class you can’t create an object of — you add the abstract keyword when declaring it. Normally the classes we create are concrete classes.

An abstract class can have an abstract method. An abstract method also begins with the abstract keyword and has no body. A method without a body is (almost always) part of an abstract class, and a class with an abstract method is automatically abstract. Since the abstract method isn’t completely defined (it lacks a body), the class itself isn’t fully defined either — so you can’t create objects of it.

abstract class Super {
Super() {
System.out.println("Super");
}
void method1() {
System.out.println("Super Method");
}
abstract void method2();
}
class Sub extends Super {
void method2() {
System.out.println("Sub Method 2");
}
}

Even though Sub inherits from Super, Sub is not an abstract class — it’s concrete. This is because Sub inherited the constructor, method1, and method2 from Super, but overrides method2, so everything in Sub is now fully defined.

If a class inherits from an abstract class, it also becomes abstract unless it overrides every method of the parent class — at which point it becomes concrete.

Why we need abstract classes

They’re meant for multiple inheritance and polymorphism — you write a subclass that inherits from the abstract superclass and overrides its methods. Abstract classes are used for defining and imposing standards.

Notes

  1. You cannot create an object of an abstract class, only a reference.
  2. You can create an object of a concrete class that inherits from the abstract class.
  3. If even one method in your child class doesn’t override the parent’s, the child class becomes abstract too.
  4. The @Override annotation on a child class isn’t a strict requirement, but it’s good practice.

Worked example

abstract class Super {
public Super() {
System.out.println("Super Constructor");
}
public void meth1() {
System.out.println("Meth1 of Super");
}
abstract public void meth2();
}
class Sub extends Super {
@Override
public void meth2() {
System.out.println("Meth2 of sub class");
}
}
public class AbstractExample {
public static void main(String[] args) {
Super s = new Sub();
s.meth1();
s.meth2();
}
}

A slightly bigger example — an abstract Hospital class that imposes a standard set of operations on any concrete hospital implementation:

abstract class Hospital {
abstract void emergency();
abstract void appointment();
abstract void admit();
abstract void billing();
}
class MyHospital extends Hospital {
MyHospital() {
}
@Override
void emergency() {
}
@Override
void appointment() {
}
@Override
void admit() {
}
@Override
void billing() {
}
}

Abstract class vs. interface, side by side

abstract class Test1 {
abstract public void meth1();
abstract public void meth2();
}
class Test2 extends Test1 {
@Override
public void meth1() {
}
@Override
public void meth2() {
}
}
interface TestOne {
void methOne();
void methTwo();
}
class TestTwo implements TestOne {
public void methOne() {
}
public void methTwo() {
}
}
public class AbstractVsInterface {
public static void main(String[] args) {
Test1 t = new Test2();
TestOne tee = new TestTwo();
}
}