Skip to main content
  1. Resources/
  2. Study Materials/
  3. Information & Communication Technology Engineering/
  4. ICT Semester 4/
  5. Java Programming (4343203)/

8 mins· ·
Milav Dabgar
Author
Milav Dabgar
Experienced lecturer in the electrical and electronic manufacturing industry. Skilled in Embedded Systems, Image Processing, Data Science, MATLAB, Python, STM32. Strong education professional with a Master’s degree in Communication Systems Engineering from L.D. College of Engineering - Ahmedabad.
Java Programming - Interfaces and Abstract Classes

Java Programming Language

Chapter 7: Interfaces and Abstract Classes

Abstraction in Java


Course: 4343203 - Java Programming

What We'll Cover

  • Abstract Classes
  • Abstract Methods
  • Interface Fundamentals
  • Interface Implementation
  • Multiple Inheritance with Interfaces
  • Default and Static Methods in Interfaces
  • Abstract Classes vs Interfaces
  • Practical Examples

Abstraction Concepts

Java Abstraction Concepts

Abstract Classes

Abstract Class is a class that cannot be instantiated and may contain abstract methods

Abstract Class Characteristics

Key Features:

  • Declared with abstract keyword
  • Cannot be instantiated directly
  • Can have both abstract and concrete methods
  • Can have constructors, fields, and static methods
  • Must be extended by concrete classes

Abstract Class Example:


abstract class Animal {
    // Concrete field
    protected String name;
    protected int age;
    
    // Constructor
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Concrete method
    public void sleep() {
        System.out.println(name + " is sleeping");
    }
    
    // Abstract method (must be implemented)
    public abstract void makeSound();
    public abstract void move();
}
                            

Concrete Implementation:


class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " barks: Woof!");
    }
    
    @Override
    public void move() {
        System.out.println(name + " runs on four legs");
    }
}

public class TestAbstract {
    public static void main(String[] args) {
        // Animal animal = new Animal(); // Error!
        
        Dog dog = new Dog("Buddy", 3);
        dog.makeSound(); // Buddy barks: Woof!
        dog.move();      // Buddy runs on four legs
        dog.sleep();     // Buddy is sleeping
    }
}
                            

Abstract Methods

Abstract Method Rules:

  • Declared with abstract keyword
  • No method body (only signature)
  • Must be implemented in concrete subclasses
  • Cannot be private, final, or static

abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Abstract methods - must be implemented
    public abstract double area();
    public abstract double perimeter();
    
    // Concrete method
    public void displayInfo() {
        System.out.println("Color: " + color);
        System.out.println("Area: " + area());
        System.out.println("Perimeter: " + perimeter());
    }
}

class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double perimeter() {
        return 2 * Math.PI * radius;
    }
}

class Rectangle extends Shape {
    private double width, height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double area() {
        return width * height;
    }
    
    @Override
    public double perimeter() {
        return 2 * (width + height);
    }
}
                    

Interfaces

Interface defines a contract that implementing classes must follow

Interface Characteristics

Key Features:

  • Declared with interface keyword
  • All methods are implicitly public and abstract
  • All fields are implicitly public, static, and final
  • Cannot be instantiated
  • Supports multiple inheritance

Interface Definition:


interface Drawable {
    // Constant (public static final)
    String TYPE = "DRAWABLE";
    
    // Abstract methods (public abstract)
    void draw();
    void resize(double factor);
}

interface Movable {
    void move(int x, int y);
    void rotate(double angle);
}

interface Printable {
    void print();
    boolean canPrint();
}
                            

Interface Implementation:


class Rectangle implements Drawable, Movable {
    private int x, y, width, height;
    
    public Rectangle(int x, int y, int w, int h) {
        this.x = x; this.y = y;
        this.width = w; this.height = h;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing rectangle at (" 
            + x + "," + y + ")");
    }
    
    @Override
    public void resize(double factor) {
        width *= factor;
        height *= factor;
    }
    
    @Override
    public void move(int newX, int newY) {
        this.x = newX;
        this.y = newY;
    }
    
    @Override
    public void rotate(double angle) {
        System.out.println("Rotating by " + angle);
    }
}
                            

Multiple Interface Implementation

Multiple Interfaces:


interface Flyable {
    void fly();
    double getAltitude();
}

interface Swimmable {
    void swim();
    double getDepth();
}

class Duck implements Flyable, Swimmable {
    private double altitude = 0;
    private double depth = 0;
    
    @Override
    public void fly() {
        altitude = 100;
        System.out.println("Duck is flying");
    }
    
    @Override
    public double getAltitude() {
        return altitude;
    }
    
    @Override
    public void swim() {
        depth = 5;
        System.out.println("Duck is swimming");
    }
    
    @Override
    public double getDepth() {
        return depth;
    }
    
    public void walk() {
        System.out.println("Duck is walking");
    }
}
                            

Interface Inheritance:


interface Vehicle {
    void start();
    void stop();
}

interface LandVehicle extends Vehicle {
    void accelerate();
    void brake();
}

interface WaterVehicle extends Vehicle {
    void sail();
    void anchor();
}

// Multiple interface inheritance
interface AmphibiousVehicle 
    extends LandVehicle, WaterVehicle {
    void switchToLandMode();
    void switchToWaterMode();
}

class AmphibiousCar 
    implements AmphibiousVehicle {
    
    @Override
    public void start() {
        System.out.println("Engine started");
    }
    
    @Override
    public void stop() {
        System.out.println("Engine stopped");
    }
    
    // Implement all other methods...
}
                            

Default and Static Methods in Interfaces

Java 8+ introduced default and static methods in interfaces

Default Methods

Default Method Features:

  • Provide default implementation in interface
  • Can be overridden in implementing classes
  • Enable interface evolution without breaking existing code
  • Declared with default keyword

Interface with Default Methods:


interface Calculator {
    // Abstract methods
    double add(double a, double b);
    double subtract(double a, double b);
    
    // Default methods
    default double multiply(double a, double b) {
        return a * b;
    }
    
    default double divide(double a, double b) {
        if (b == 0) {
            throw new ArithmeticException("Division by zero");
        }
        return a / b;
    }
    
    default void printResult(double result) {
        System.out.println("Result: " + result);
    }
}
                            

Implementation:


class BasicCalculator implements Calculator {
    @Override
    public double add(double a, double b) {
        return a + b;
    }
    
    @Override
    public double subtract(double a, double b) {
        return a - b;
    }
    
    // Can override default methods if needed
    @Override
    public void printResult(double result) {
        System.out.println("Calculation result: " + result);
    }
    
    // multiply() and divide() are inherited
}

public class TestDefault {
    public static void main(String[] args) {
        Calculator calc = new BasicCalculator();
        
        double sum = calc.add(10, 5);
        calc.printResult(sum); // Uses overridden method
        
        double product = calc.multiply(4, 3);
        calc.printResult(product); // Uses default method
    }
}
                            

Static Methods in Interfaces

Interface with Static Methods:


interface MathUtils {
    // Static constants
    double PI = 3.14159;
    double E = 2.71828;
    
    // Abstract method
    double calculate();
    
    // Static methods
    static double square(double x) {
        return x * x;
    }
    
    static double cube(double x) {
        return x * x * x;
    }
    
    static double power(double base, double exp) {
        return Math.pow(base, exp);
    }
    
    static boolean isEven(int num) {
        return num % 2 == 0;
    }
    
    static boolean isPrime(int num) {
        if (num < 2) return false;
        for (int i = 2; i <= Math.sqrt(num); i++) {
            if (num % i == 0) return false;
        }
        return true;
    }
}
                            

Using Static Methods:


class NumberProcessor implements MathUtils {
    private double value;
    
    public NumberProcessor(double value) {
        this.value = value;
    }
    
    @Override
    public double calculate() {
        return MathUtils.square(value);
    }
}

public class TestStatic {
    public static void main(String[] args) {
        // Call static methods directly
        double result1 = MathUtils.square(5);
        double result2 = MathUtils.cube(3);
        
        System.out.println("5² = " + result1);
        System.out.println("3³ = " + result2);
        
        // Check if numbers are prime
        System.out.println("Is 17 prime? " + 
            MathUtils.isPrime(17));
        System.out.println("Is 20 even? " + 
            MathUtils.isEven(20));
        
        // Use with implementing class
        NumberProcessor processor = 
            new NumberProcessor(4);
        System.out.println("Calculated: " + 
            processor.calculate());
    }
}
                            

Abstract Classes vs Interfaces

Interface vs Abstract Class Comparison

Detailed Feature Comparison

FeatureAbstract ClassInterface
Keywordabstract classinterface
InheritanceSingle inheritance (extends)Multiple inheritance (implements)
MethodsAbstract and concrete methodsAbstract, default, and static methods
FieldsAny type of fieldsOnly public static final constants
ConstructorCan have constructorsCannot have constructors
Access ModifiersAll access modifiersMethods are public by default
InstantiationCannot be instantiatedCannot be instantiated
Use CaseWhen classes share common codeWhen defining contracts for behavior

Practical Examples

Real-World Example: Media Player


// Interface for playable media
interface Playable {
    void play();
    void pause();
    void stop();
    double getDuration();
    
    // Default method
    default void displayInfo() {
        System.out.println("Media duration: " + getDuration() + " seconds");
    }
}

// Abstract class for media files
abstract class MediaFile implements Playable {
    protected String fileName;
    protected double fileSize;
    protected boolean isPlaying;
    
    public MediaFile(String fileName, double fileSize) {
        this.fileName = fileName;
        this.fileSize = fileSize;
        this.isPlaying = false;
    }
    
    // Concrete method
    public void displayFileInfo() {
        System.out.println("File: " + fileName + " (" + fileSize + " MB)");
    }
    
    // Abstract method
    public abstract String getFormat();
}

// Concrete implementations
class AudioFile extends MediaFile {
    private double duration;
    
    public AudioFile(String fileName, double fileSize, double duration) {
        super(fileName, fileSize);
        this.duration = duration;
    }
    
    @Override
    public void play() {
        isPlaying = true;
        System.out.println("Playing audio: " + fileName);
    }
    
    @Override
    public void pause() {
        System.out.println("Audio paused: " + fileName);
    }
    
    @Override
    public void stop() {
        isPlaying = false;
        System.out.println("Audio stopped: " + fileName);
    }
    
    @Override
    public double getDuration() {
        return duration;
    }
    
    @Override
    public String getFormat() {
        return "MP3";
    }
}

class VideoFile extends MediaFile {
    private double duration;
    private String resolution;
    
    public VideoFile(String fileName, double fileSize, double duration, String resolution) {
        super(fileName, fileSize);
        this.duration = duration;
        this.resolution = resolution;
    }
    
    @Override
    public void play() {
        isPlaying = true;
        System.out.println("Playing video: " + fileName + " (" + resolution + ")");
    }
    
    @Override
    public void pause() {
        System.out.println("Video paused: " + fileName);
    }
    
    @Override
    public void stop() {
        isPlaying = false;
        System.out.println("Video stopped: " + fileName);
    }
    
    @Override
    public double getDuration() {
        return duration;
    }
    
    @Override
    public String getFormat() {
        return "MP4";
    }
}

// Usage
public class MediaPlayerDemo {
    public static void main(String[] args) {
        Playable[] playlist = {
            new AudioFile("song1.mp3", 5.2, 210),
            new VideoFile("movie.mp4", 1200, 7200, "1080p"),
            new AudioFile("song2.mp3", 4.8, 180)
        };
        
        for (Playable media : playlist) {
            if (media instanceof MediaFile) {
                ((MediaFile) media).displayFileInfo();
            }
            media.displayInfo();
            media.play();
            System.out.println();
        }
    }
}
                    

Chapter Summary

Abstract Classes:

  • Partial implementation with abstract methods
  • Cannot be instantiated
  • Support constructors and instance variables
  • Single inheritance only
  • Mix of abstract and concrete methods

Interfaces:

  • Pure contracts with method signatures
  • Support multiple inheritance
  • Default and static methods (Java 8+)
  • All fields are constants
  • Achieve loose coupling

Next: Packages and Access Control

Thank You!

Questions?


Ready to explore Packages and Access Control!