Start learning free

LESSON 185 OF 344 · OBJECT-ORIENTED PROGRAMMING

Abstract Classes in Java: abstract Methods and Subclasses

Lesson Read the full explanation

TL ; DR:

An abstract class is a class you can't instantiate directly — it's a half-finished template. It can declare methods with no body (abstract methods) that any concrete subclass must implement.


abstract class Animal {
    public abstract void speak();   // no body — concrete
                                      // subclasses must provide one
}
class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Woof");
    }
}


Full lesson:

Sometimes you want to capture shared behavior across a family of classes without committing to one concrete implementation. For example, every Animal can speak(), but exactly how depends on whether it's a Dog or a Cat. That's what abstract classes are for.

Two superpowers

  1. You can't write new Animal() directly — the compiler/runtime stops you. You have to pick a concrete subclass.
  2. Any subclass MUST implement every abstract method, or the compiler/runtime complains. The abstract class is a contract with teeth.

Mixing abstract and concrete

An abstract class can also have concrete methods (with bodies) and fields. Those are shared by all subclasses for free, just like normal inheritance. Only the methods marked abstract require an override.

Notes by language

  • C# / Java — keyword abstract on the class and on the method.
  • Python — inherit from abc.ABC and decorate the method with @abstractmethod.
  • JavaScript — no built-in support. The convention is a parent class whose method throws an error if not overridden.
  • C++ — a method ending with = 0 is "pure virtual"; a class with any pure virtual method is abstract.

Your task

The abstract Animal class is already defined. Create a concrete Dog subclass and implement the speak method so it prints "Woof". The harness builds a Dog and calls speak().

Expected output:

Woof
STEP 1 OF 2
    Ctrl + Enter to check

    JAVA · OBJECT-ORIENTED PROGRAMMING

    Abstract Classes in Java, explained

    What an abstract class is

    Sometimes a family of classes shares a behavior, but each member does it differently. Every Animal can speak(), yet how it speaks depends on whether it is a dog or a cat. An abstract class captures the shared part and leaves the rest for subclasses to fill in. It is a half-finished template that you can't use on its own.

    The syntax

    Put the abstract keyword on the class, and on any method that has no body:

    abstract class Animal {
        public abstract void speak();
    }
    

    An abstract method has a signature followed by a semicolon instead of a body. It declares what every subclass must be able to do without saying how.

    Two rules with teeth

    1. You can't create an abstract class with new. Writing new Animal() is a compile error: Animal is abstract; cannot be instantiated. You must create an object of a concrete subclass.
    2. A concrete subclass must implement every abstract method. If it doesn't, the compiler refuses to compile it, with a message such as Dog is not abstract and does not override abstract method speak() in Animal.

    Together these make the abstract class a contract that the compiler enforces. Anyone holding an Animal knows it can speak, because no object of a half-finished class can ever exist.

    Mixing abstract and concrete members

    An abstract class may also contain ordinary methods with bodies, fields and constructors. Subclasses inherit them like any other members. Only the methods marked abstract must be overridden. This lets a template fix the common steps and leave one step open:

    abstract class Shape {
        public abstract double area();
    
        public String describe() {
            return "area " + area();
        }
    }
    
    class Square extends Shape {
        private double s;
    
        public Square(double s) {
            this.s = s;
        }
    
        @Override
        public double area() {
            return s * s;
        }
    }
    

    With these definitions, new Square(3).describe() returns area 9.0. The concrete describe in Shape calls area(), and Java runs Square's version, because the object is a Square. This is the same dynamic dispatch as in the polymorphism lesson.

    The lesson's exercise, step by step

    The starter code defines the abstract Animal with one abstract method, and a mainFunction that creates a Dog and calls speak() on it. Dog does not exist yet. Two steps provide it:

    1. Declare the subclass. Below Animal, write class Dog extends Animal. An abstract class can only be used through a concrete subclass, so this class is what makes Animal usable.
    2. Implement the method. Inside Dog, write public void speak() with @Override and print "Woof". The method must be public, like the abstract one it replaces.

    The finished program:

    abstract class Animal {
        public abstract void speak();
    }
    
    class Dog extends Animal {
        @Override
        public void speak() {
            System.out.println("Woof");
        }
    }
    
    class Solution {
        public void mainFunction() {
            Dog rex = new Dog();
            rex.speak();
        }
    }
    

    It prints:

    Woof
    

    Without the method body, Dog would fail to compile, since it would inherit an abstract method it never implemented. Without extends Animal, the contract wouldn't apply, and Dog would be an unrelated class.

    Details worth knowing

    • Abstract variables are fine. You can't write new Animal(), but a variable of type Animal is allowed and can refer to any concrete subclass object: Animal pet = new Dog();.
    • Abstract methods have no body. Adding braces, as in public abstract void speak() { }, is a compile error.
    • A class with an abstract method must be abstract. Declaring an abstract method inside a normal class doesn't compile.
    • An abstract class can have no abstract methods. That is legal. It simply cannot be instantiated.
    • Subclasses can stay abstract. A subclass that implements only some of the abstract methods must itself be declared abstract.
    • Abstract and private don't mix. An abstract method is meant to be overridden, so it can't be private, final or static.
    • Interfaces are a related tool. A class extends only one parent but may implement several interfaces. Abstract classes are best when subclasses share fields or code.

    Common mistakes

    • Instantiating the abstract class. new Animal() never compiles, whatever the arguments.
    • Forgetting to implement the method. Every concrete subclass needs a body for every abstract method it inherits.
    • Getting the signature wrong. public void speak(int times) is a different method and doesn't implement speak(). With @Override the compiler reports the mistake.
    • Narrowing access. Writing void speak() without public in Dog is an error, because an override can't be less visible than the method it replaces.
    • Forgetting extends. A class with the right method but no extends Animal doesn't count as an animal.

    Key takeaways

    • An abstract class is a template you can't instantiate directly.
    • An abstract method has no body, and every concrete subclass must implement it.
    • Abstract classes can also hold fields and ordinary methods that subclasses inherit.
    • Variables may have the abstract type and hold subclass objects, so polymorphism still works.
    • The compiler enforces the contract: missing implementations are compile errors, not runtime surprises.
    Keep going with JavaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free