Object-Oriented Programming in Java: An Academic Perspective



This content originally appeared on DEV Community and was authored by Rifat Khan

This article presents a comprehensive overview of the principal concepts of Object-Oriented Programming (OOP) in Java. The treatment is designed for academic study, combining theoretical foundations with practical examples to provide a well-rounded understanding. Each section introduces a concept, outlines its syntax, highlights its significance, and offers illustrative code samples.

Table of Contents

  1. Introduction to OOP in Java
  2. Constructor and Method Overloading
  3. Method Overriding
  4. Inheritance
  5. Returning Objects from Methods
  6. The super Keyword
  7. The this Keyword
  8. The static Keyword
  9. The final Keyword
  10. Dynamic Method Dispatch
  11. Abstract Classes
  12. Interfaces
  13. Summary of Keywords
  14. Best Practices
  15. Exercises for Students
  16. Conclusion

Introduction to OOP in Java

Java was designed with Object-Oriented Programming (OOP) principles at its core. OOP allows developers to model real-world systems through objects, which encapsulate both state (attributes) and behavior (methods). The four fundamental principles of OOP are:

  • Encapsulation: Grouping data and related behavior while restricting external access.
  • Abstraction: Exposing essential features while concealing implementation details.
  • Inheritance: Allowing a new class to acquire the properties and behavior of an existing class.
  • Polymorphism: Supporting multiple forms of behavior through method overloading and overriding.

Constructor and Method Overloading

Overloading refers to defining multiple constructors or methods with the same name but different parameter lists. Overloading is resolved at compile time.

Syntax Example

class Student {
    String name;
    int age;

    // Constructor overloading
    Student() { this("Unknown", 0); }
    Student(String name) { this(name, 18); }
    Student(String name, int age) { this.name = name; this.age = age; }

    // Method overloading
    void showInfo() { System.out.println(name + " - " + age); }
    void showInfo(String prefix) { System.out.println(prefix + ": " + name + " - " + age); }
}

Academic Note

Overloading is an example of compile-time polymorphism. It provides flexibility by allowing different parameterizations of methods or constructors.

Method Overriding

Overriding occurs when a subclass provides its own implementation for a method already defined in the superclass. Resolution occurs at runtime.

class Animal {
    void sound() { System.out.println("Generic animal sound"); }
}
class Dog extends Animal {
    @Override
    void sound() { System.out.println("Dog barks"); }
}

Academic Note

Overriding exemplifies runtime polymorphism, which enables dynamic behavior adjustment.

Inheritance

Inheritance allows classes to reuse fields and methods from other classes using the extends keyword.

class Person {
    String name;
    void greet() { System.out.println("Hello, I am " + name); }
}
class Employee extends Person {
    int salary;
}

Academic Note

Inheritance should represent a true “is-a” relationship. Excessive inheritance hierarchies are discouraged due to maintenance challenges.

Returning Objects from Methods

Java methods can return objects, allowing construction of new instances within methods.

class Box {
    int length;
    Box(int length) { this.length = length; }
    Box duplicate() { return new Box(this.length); }
}

The super Keyword

super refers to the immediate parent class. It is used to:

  1. Invoke parent constructors.
  2. Access parent methods and variables.
class Parent {
    int num = 100;
    void show() { System.out.println("Parent method"); }
}
class Child extends Parent {
    @Override
    void show() {
        super.show();
        System.out.println("Child method, Parent num = " + super.num);
    }
}

The this Keyword

this refers to the current object instance.

class Example {
    int x;
    Example(int x) { this.x = x; }
    void display() { System.out.println("Value: " + this.x); }
}

The static Keyword

Static members belong to the class rather than an instance.

class Counter {
    static int count = 0;
    Counter() { count++; }
}

Academic Note

Static methods and variables should be used judiciously, as they compromise object-oriented design by introducing global state.

The final Keyword

The final keyword prevents modification or extension.

  • Final variables: cannot be reassigned.
  • Final methods: cannot be overridden.
  • Final classes: cannot be inherited.
final class Vehicle {
    final int speedLimit = 100;
    final void displayLimit() { System.out.println("Speed limit: " + speedLimit); }
}

Dynamic Method Dispatch

Dynamic method dispatch resolves overridden methods at runtime.

class A { void show() { System.out.println("A.show"); } }
class B extends A { @Override void show() { System.out.println("B.show"); } }

A ref = new B();
ref.show(); // B.show

Abstract Classes

Abstract classes cannot be instantiated. They may contain both abstract methods (without implementations) and concrete methods.

abstract class Shape {
    abstract double area();
    void describe() { System.out.println("I am a shape"); }
}
class Circle extends Shape {
    double r;
    Circle(double r) { this.r = r; }
    @Override double area() { return Math.PI * r * r; }
}

Interfaces

An interface specifies a contract that a class must implement.

interface Drawable { void draw(); }
class Rectangle implements Drawable {
    public void draw() { System.out.println("Drawing Rectangle"); }
}

Summary of Keywords

Keyword Primary Function
this Refers to the current object instance.
super Refers to the immediate superclass.
static Defines class-level members.
final Declares constants, immutable methods, and non-inheritable classes.
abstract Declares abstract classes and methods.
interface Declares a contract of methods to be implemented.

Best Practices

  • Prefer composition over inheritance for flexibility.
  • Keep fields private; expose behavior through methods.
  • Avoid excessive reliance on static members.
  • Use @Override annotations for clarity and safety.

Exercises for Students

  1. Implement a Logger class with overloaded methods for different input types.
  2. Create a base class Payment and subclasses CardPayment and MobilePayment. Demonstrate overriding and dynamic method dispatch.
  3. Define an abstract class Storage and an interface KeyValueStore. Implement InMemoryStore to combine both.

Conclusion

Object-Oriented Programming in Java provides a robust framework for structuring programs in a modular and maintainable manner. Through the concepts of encapsulation, abstraction, inheritance, and polymorphism, developers can model complex systems effectively. Mastery of keywords such as this, super, static, final, and constructs such as abstract classes and interfaces, is crucial for academic and professional proficiency in Java programming.


This content originally appeared on DEV Community and was authored by Rifat Khan