Abstract and concrete classes help organize code by defining what things can do and how they do it. Abstract classes set rules, while concrete classes fill in the details.
Abstract vs concrete classes in Java
Start learning this pattern below
Jump into concepts and practice - no test required
abstract class Animal { // Abstract method (no body) abstract void makeSound(); // Concrete method (has body) void sleep() { System.out.println("This animal is sleeping."); } } class Dog extends Animal { // Must implement abstract method void makeSound() { System.out.println("Woof Woof"); } } class Cat extends Animal { void makeSound() { System.out.println("Meow"); } }
An abstract class cannot be used to create objects directly.
Concrete classes must implement all abstract methods from their abstract parent.
abstract class Vehicle { abstract void startEngine(); } class Car extends Vehicle { void startEngine() { System.out.println("Car engine started."); } }
abstract class Shape { abstract double area(); } class Circle extends Shape { double radius; Circle(double radius) { this.radius = radius; } double area() { return Math.PI * radius * radius; } }
abstract class EmptyAbstract { abstract void doNothing(); } // No concrete class yet, so no objects can be created.
class ConcreteClass { void greet() { System.out.println("Hello!"); } } // Concrete class can be used to create objects directly.
This program shows an abstract class Animal with an abstract method makeSound() and a concrete method sleep(). Dog and Cat are concrete classes that implement makeSound(). We create Dog and Cat objects and call their methods.
abstract class Animal { abstract void makeSound(); void sleep() { System.out.println("This animal is sleeping."); } } class Dog extends Animal { void makeSound() { System.out.println("Woof Woof"); } } class Cat extends Animal { void makeSound() { System.out.println("Meow"); } } public class Main { public static void main(String[] args) { // Animal animal = new Animal(); // Error: cannot instantiate abstract class Dog dog = new Dog(); Cat cat = new Cat(); System.out.println("Dog says:"); dog.makeSound(); dog.sleep(); System.out.println("Cat says:"); cat.makeSound(); cat.sleep(); } }
Time complexity: Abstract vs concrete classes do not affect time complexity directly; they organize code structure.
Space complexity: No extra space cost; just class definitions.
Common mistake: Trying to create an object from an abstract class causes a compile error.
Use abstract classes when you want to define a common interface and share code but prevent direct instantiation.
Use concrete classes when you want to create usable objects with full behavior.
Abstract classes define methods without full details and cannot create objects directly.
Concrete classes provide full method details and can create objects.
Use abstract classes to set rules and concrete classes to do the actual work.
Practice
Solution
Step 1: Understand abstract class definition
An abstract class can have methods without implementation (abstract methods) and cannot create objects directly.Step 2: Compare with other options
Concrete classes have full method implementations and can be instantiated. Interfaces differ from abstract classes. Static-only classes are unrelated.Final Answer:
It can have methods without implementation and cannot be instantiated directly. -> Option CQuick Check:
Abstract class = no direct objects [OK]
- Thinking abstract classes can be instantiated
- Confusing abstract classes with interfaces
- Assuming all methods must be implemented
Solution
Step 1: Recall Java syntax for abstract classes
The keyword 'abstract' comes before 'class' followed by the class name.Step 2: Check each option
Only 'abstract class Vehicle {}' matches correct syntax. The other options have incorrect keyword order.Final Answer:
abstract class Vehicle {} -> Option AQuick Check:
abstract keyword before class name [OK]
- Placing 'abstract' after 'class'
- Mixing keyword order
- Omitting 'abstract' keyword
abstract class Animal {
abstract void sound();
}
class Dog extends Animal {
void sound() {
System.out.println("Bark");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Dog();
a.sound();
}
}Solution
Step 1: Understand class hierarchy and method overriding
Animal is abstract with abstract method sound(). Dog extends Animal and implements sound() printing "Bark".Step 2: Analyze main method execution
Animal reference points to Dog object. Calling a.sound() runs Dog's sound(), printing "Bark".Final Answer:
Bark -> Option DQuick Check:
Abstract method overridden = Dog's output [OK]
- Expecting abstract class method to run
- Thinking abstract class can be instantiated
- Confusing compile and runtime errors
abstract class Shape {
abstract void draw();
}
class Circle extends Shape {
// No draw() method implemented
}
public class Test {
public static void main(String[] args) {
Circle c = new Circle();
c.draw();
}
}Solution
Step 1: Check subclass implementation of abstract methods
Circle extends Shape but does not implement abstract method draw().Step 2: Understand Java rules for abstract methods
A concrete class must implement all abstract methods or be declared abstract itself. Circle is concrete but missing draw().Final Answer:
Circle must implement the abstract method draw() or be declared abstract. -> Option AQuick Check:
Concrete subclass must implement all abstract methods [OK]
- Thinking abstract methods can be skipped
- Assuming abstract class can't have abstract methods
- Believing object creation is the error
Solution
Step 1: Identify need for shared rules with different implementations
Employee types share concept of salary calculation but differ in details.Step 2: Use abstract class with abstract method
Abstract class Employee defines calculateSalary() abstractly. Subclasses implement specific logic.Step 3: Evaluate other options
Create only concrete classes for each employee type without any abstract class. lacks shared abstraction. Use an interface with no methods and concrete classes implementing it. uses interface with no methods, so no contract. Create a concrete Employee class with a fixed calculateSalary() method used by all employees. fixes salary calculation, no variation.Final Answer:
Create an abstract class Employee with an abstract method calculateSalary(), then create concrete subclasses like Manager and Developer implementing it. -> Option BQuick Check:
Abstract class sets rules, subclasses do work [OK]
- Not using abstraction for shared behavior
- Using concrete class with fixed method only
- Interfaces without methods don't enforce contracts
