OOP in Java
Table of contents
- 1. Classes and Objects
- 2. Constructors
- 3. Static Keyword
- 4. Singleton Class
- 5. Inheritance
- 6. Interfaces
- 7. Polymorphism
- 8. Access Modifiers
- 9. Encapsulation
- 10. Abstraction
- 11. Object Class
- 12. Annotations
- 13. Collection Framework in Java
- Theory
- Key Interfaces in Collection Framework
- 1. List Interface (Ordered Collection, Allows Duplicates)
- 2. Set Interface (Unique Elements, No Duplicates)
- 3. Queue Interface (FIFO – First In, First Out)
- 4. Map Interface (Key-Value Pairs)
- Additional Concepts in Collection Framework
- When to Use Which Collection?
- Summary
- 14. Vector Class
- 15. Enums
- Conclusion
Java is one of the most popular programming languages, and its power lies in its Object-Oriented Programming (OOP) model. OOP makes code reusable, scalable, and easier to maintain by structuring it around objects rather than functions. This blog will cover all essential OOP concepts in Java briefly, with real-world use cases and code snippets for reference.
1. Classes and Objects
Theory
A class is a blueprint or template for creating objects. It defines the properties (fields) and behaviors (methods) that objects of the class will have. An object, on the other hand, is an instance of a class that holds real data in memory.
Use Case
Consider a banking application where an Account
class defines properties like balance
and accountNumber
, while the objects represent actual customer accounts.
Code:
class Account {
int accountNumber;
double balance;
void deposit(double amount) {
balance += amount;
}
void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
} else {
System.out.println("Insufficient balance!");
}
}
}
public class Main {
public static void main(String[] args) {
Account acc1 = new Account();
acc1.accountNumber = 12345;
acc1.deposit(5000);
acc1.withdraw(2000);
}
}
2. Constructors
Theory
A constructor is a special method that initializes an object when it is created. It has the same name as the class and does not have a return type.
Use Case
Useful for setting initial values for objects, like assigning default account balance in a banking system.
Code:
class Account {
int accountNumber;
double balance;
Account(){
// Deafult constructor
}
Account(int accNum, double initialBalance) {
this.accountNumber = accNum;
this.balance = initialBalance;
}
}
public class Main {
public static void main(String[] args) {
Account acc1 = new Account(12345, 5000);
System.out.println("Account Created with Balance: " + acc1.balance);
}
}
3. Static Keyword
Theory
The static
keyword in Java is used for memory management. A static
variable or method belongs to the class rather than any specific object.
Use Case
We can call the static functions without creating an object of the respective class.
Code:
class Bank {
static double interestRate = 5.5;
}
public class Main {
public static void main(String[] args) {
System.out.println("Interest Rate: " + Bank.interestRate);
}
}
4. Singleton Class
Theory
A singleton class ensures that only one instance of the class is created and shared.
Code:
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
System.out.println(obj1 == obj2); // true
}
}
5. Inheritance
Theory
Inheritance allows one class to acquire the properties and behaviors of another class. The parent class (superclass) provides common functionalities, while the child class (subclass) extends it, adding or modifying features.
Types of Inheritance:
We don’t have Multiple Inheritance in Java as we need to implement Interfaces for that.
Use Case
Commonly used in hierarchical relationships like Animal → Pets→ Dog, where all pets share some traits but dogs have specific characteristics.
Code:
class Animal {
void eat() {
System.out.println("This animal eats food");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.eat(); // Inherited from Animal
d.bark();
}
}
6. Interfaces
Theory
An interface in Java defines a contract that implementing classes must follow. Unlike abstract classes, interfaces cannot contain concrete methods.
Use Case
Used in frameworks and APIs, such as Java’s Collection Framework, where List
, Set
, and Queue
implement the Collection
interface.
Code:
interface Animal {
void makeSound();
}
class Cat implements Animal {
public void makeSound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal myCat = new Cat();
myCat.makeSound();
}
}
7. Polymorphism
Theory
Polymorphism allows objects to take multiple forms. It is categorized into two types:
Compile-time Polymorphism (Method Overloading)
Runtime Polymorphism (Method Overriding)
Use Case
Polymorphism is useful when different classes share the same method but behave differently, such as different shapes having their own implementation of area()
.
Code:
// Compile-time Polymorphism (Method Overloading)
class Shape {
void draw() {
System.out.println("Drawing a shape");
}
void draw(String color) { // Overloaded method
System.out.println("Drawing a shape in " + color);
}
}
// Runtime Polymorphism (Method Overriding)
class Circle extends Shape {
void draw() {
System.out.println("Drawing a Circle");
}
}
class Rectangle extends Shape {
void draw() {
System.out.println("Drawing a Rectangle");
}
}
class Triangle extends Shape {
void draw() {
System.out.println("Drawing a Triangle");
}
}
public class Main {
public static void main(String[] args) {
// Compile-time polymorphism (Method Overloading)
Shape shape = new Shape();
shape.draw();
shape.draw("Red");
System.out.println("---------------------");
// Runtime polymorphism (Method Overriding)
Shape s1 = new Circle();
Shape s2 = new Rectangle();
Shape s3 = new Triangle();
s1.draw(); // Drawing a Circle
s2.draw(); // Drawing a Rectangle
s3.draw(); // Drawing a Triangle
}
}
8. Access Modifiers
Theory
Access modifiers control the visibility of class members. The four types are:
private
→ Accessible within the same class.default
→ Accessible within the same package.protected
→ Accessible within the same package and subclasses.public
→ Accessible everywhere.
Use Case
Used for maintaining security and preventing unauthorized access to critical data.
9. Encapsulation
Theory
Encapsulation is the practice of restricting direct access to data fields and only allowing modifications through methods that ensure data integrity.
Use Case
Used in real-world applications like banking, where private fields such as balance should only be modified using methods like deposit()
and withdraw()
.
Code:
class BankAccount {
private double balance;
// Getter method to access balance
public double getBalance() {
return balance;
}
// Setter method to modify balance safely
public void setBalance(double balance) {
if (balance >= 0) {
this.balance = balance;
} else {
System.out.println("Balance cannot be negative!");
}
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
} else {
System.out.println("Deposit amount must be positive!");
}
}
}
public class Main {
public static void main(String[] args) {
BankAccount acc = new BankAccount();
// Using setter to initialize balance
acc.setBalance(1000);
// Depositing money
acc.deposit(5000);
// Getting balance using getter
System.out.println("Balance: " + acc.getBalance());
}
}
10. Abstraction
Theory
Abstraction hides implementation details from the user, exposing only essential features. It is achieved using abstract classes.
Use Case
ATM machines provide a simple interface for users without exposing internal mechanisms like cash withdrawal processing.
Code:
abstract class Vehicle {
abstract void start(); // Abstract method
}
class Car extends Vehicle {
void start() {
System.out.println("Car starts with a key");
}
}
public class Main {
public static void main(String[] args) {
Vehicle myCar = new Car();
myCar.start();
}
}
11. Object Class
Theory
All Java classes are inherited from the Object
class, which provides methods like toString()
, equals()
, and hashCode()
.
12. Annotations
Theory
Annotations provide metadata about code, helping tools like compilers and frameworks process it correctly.
Use Case
Used for marking methods as deprecated, overriding methods.
Code:
class Parent {
void show() {
System.out.println("Parent class");
}
}
class Child extends Parent {
@Override
void show() {
System.out.println("Child class");
}
}
13. Collection Framework in Java
Theory
The Java Collection Framework (JCF) is a unified architecture that provides ready-to-use data structures and algorithms to store, manipulate, and retrieve data efficiently. It contains multiple interfaces (like List
, Set
, Map
, Queue
) and concrete implementations (like ArrayList
, HashSet
, HashMap
, etc.).
This framework is part of java.util
package and helps developers avoid reinventing the wheel by providing optimized implementations of commonly used data structures.
Key Interfaces in Collection Framework
List Interface – Ordered collection (allows duplicates)
Set Interface – Unordered collection (no duplicates)
Queue Interface – Follows FIFO (First In, First Out)
Map Interface – Stores key-value pairs
1. List Interface (Ordered Collection, Allows Duplicates)
The List
interface allows storing ordered elements with duplicate values and provides positional access.
Implementations:
ArrayList
– Resizable array, fast read, slow insert/removeLinkedList
– Doubly linked list, fast insert/remove, slow readVector
– Thread-safe version ofArrayList
Example: ArrayList
javaCopyEditimport java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Alice"); // Duplicates are allowed
System.out.println(names); // [Alice, Bob, Alice]
}
}
2. Set Interface (Unique Elements, No Duplicates)
The Set
interface ensures only unique elements are stored.
Implementations:
HashSet
– Uses hashing (fastest, no order)LinkedHashSet
– Maintains insertion orderTreeSet
– Stores elements in sorted order
Example: HashSet
javaCopyEditimport java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<Integer> numbers = new HashSet<>();
numbers.add(10);
numbers.add(20);
numbers.add(10); // Duplicate, won't be added
System.out.println(numbers); // [10, 20]
}
}
3. Queue Interface (FIFO – First In, First Out)
Queues, like a task scheduler, are useful when processing elements in sequential order.
Implementations:
LinkedList
(as a queue) – Doubly linked listPriorityQueue
– Orders elements based on priority
Example: PriorityQueue
javaCopyEditimport java.util.PriorityQueue;
public class Main {
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(30);
pq.add(10);
pq.add(20);
System.out.println(pq.poll()); // 10 (smallest first)
}
}
4. Map Interface (Key-Value Pairs)
Map
stores data in key-value pairs.
Implementations:
HashMap
– Unordered, allowsnull
keysLinkedHashMap
– Maintains insertion orderTreeMap
– Sorted by keys
Example: HashMap
javaCopyEditimport java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> studentMarks = new HashMap<>();
studentMarks.put("Alice", 95);
studentMarks.put("Bob", 88);
System.out.println(studentMarks.get("Alice")); // 95
}
}
Additional Concepts in Collection Framework
Iterable & Iterator (Traversing Collections)
Every collection implements Iterable
, which allows looping using an Iterator.
Example: Iterating a List Using Iterator
javaCopyEditimport java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
When to Use Which Collection?
Collection Type | Best Use Case |
ArrayList | Fast random access, dynamic arrays |
LinkedList | Fast insertions/deletions |
HashSet | Unordered unique elements |
TreeSet | Sorted unique elements |
HashMap | Key-value pairs, fast lookup |
PriorityQueue | Elements processed by priority |
Summary
Java's Collection Framework provides efficient data structures for different needs.
List
(Ordered, allows duplicates) → Use ArrayList, LinkedList.Set
(Unique elements) → Use HashSet, TreeSet.Queue
(FIFO) → Use LinkedList, PriorityQueue.Map
(Key-Value) → Use HashMap, TreeMap.
14. Vector Class
Theory
Vector
is a synchronized, resizable array implementation in Java.
Use Case
Used in multi-threaded environments where thread safety is required.
Code:
import java.util.Vector;
public class Main {
public static void main(String[] args) {
Vector<Integer> numbers = new Vector<>();
numbers.add(10);
numbers.add(20);
System.out.println(numbers);
}
}
15. Enums
Theory
Enums define a set of named constants, improving code readability and reducing errors.
Use Case
Used for defining predefined values like days of the week or status codes.
Code:
enum Day { MONDAY, TUESDAY, WEDNESDAY }
public class Main {
public static void main(String[] args) {
Day today = Day.MONDAY;
System.out.println("Today is " + today);
}
}
Conclusion
Object-oriented programming in Java provides powerful tools for designing robust applications. Mastering these concepts will help you write clean, scalable, and efficient Java code as I’m practicing It while building Android apps. Keep practicing and applying these concepts in real-world projects!