OOP
What is OOP
OOP stands for Object-Oriented Programming.
Procedural programming is about writing procedures or methods that perform operations on the data, while object-oriented programming is about creating objects that contain both data and methods.
Object-oriented programming has several advantages over procedural programming:
- OOP is faster and easier to execute
- OOP provides a clear structure for the programs
- OOP helps to keep the Java code DRY "Don't Repeat Yourself", and makes the code easier to maintain, modify and debug
- OOP makes it possible to create full reusable applications with less code and shorter development time
Inheritance
Inheritance in Java
Inheritance in Java is a mechanism that allows a class to inherit the properties and behaviors (fields and methods) of another class. The class whose members are inherited is called the superclass (parent class), and the class that inherits is called the subclass (child class).
Through inheritance, a subclass can access the members of its superclass, which helps in code reusability and promotes a clear hierarchical structure in programs.
Inheritance represents the “IS-A” relationship, also known as a parent-child relationship, where the subclass is a specialized form of the superclass.
Key Features of Inheritance
Method Overriding:
Inheritance allows a subclass to provide a specific implementation of a method already defined in its superclass. This is known as runtime polymorphism.
Code Reusability:
Inheritance allows developers to reuse existing code from a parent class. This reduces redundancy and makes the code easier to maintain.
Terms Used in Inheritance
Class:
A class is a group of objects with common properties. It acts as a blueprint or template for creating objects.
Subclass (Child Class):
A subclass is a class that inherits another class. It is also called a derived class or extended class.
Superclass (Parent Class):
A superclass is the class from which a subclass inherits features. It is also known as a base class.
Reusability:
Reusability is the ability to use existing fields and methods of a class when creating a new class, avoiding duplication.
Types of Inheritance in Java
Single Inheritance:
A subclass inherits from only one superclass.
Multilevel Inheritance:
A class is derived from another subclass, forming a chain of inheritance.
Hierarchical Inheritance:
Multiple subclasses inherit from the same superclass.
Hybrid Inheritance (Through Interfaces):
Hybrid inheritance is a combination of two or more types of inheritance. In Java, it is achieved using interfaces.
Important Note
Java does not support multiple inheritance with classes directly to avoid ambiguity problems. However, it supports multiple and hybrid inheritance through interfaces.
Example
Single Inheritance Example
class Animal {
void eat() {
System.out.println("eating...");
}
}
class Dog extends Animal {
void bark() {
System.out.println("barking...");
}
}
public class Main {
public static void main(String args[]) {
Dog d = new Dog();
d.bark();
d.eat();
}
}
Multilevel Inheritance Example
class Animal {
void eat() {
System.out.println("eating...");
}
}
class Dog extends Animal {
void bark() {
System.out.println("barking...");
}
}
class BabyDog extends Dog {
void weep() {
System.out.println("weeping...");
}
}
public class Main {
public static void main(String args[]) {
BabyDog d = new BabyDog();
d.weep();
d.bark();
d.eat();
}
}
Hierarchical Inheritance Example
class Animal {
void eat() {
System.out.println("eating...");
}
}
class Dog extends Animal {
void bark() {
System.out.println("barking...");
}
}
class Cat extends Animal {
void meow() {
System.out.println("meowing...");
}
}
public class Main {
public static void main(String args[]) {
Cat c = new Cat();
c.meow();
c.eat();
// c.bark(); // Compile Time Error
}
}
Multiple / Hybrid Inheritance
interface Character {
void attack();
}
interface Weapon {
void use();
}
class Warrior implements Character, Weapon {
public void attack() {
System.out.println("Warrior attacks with a sword.");
}
public void use() {
System.out.println("Warrior uses a sword.");
}
}
class Mage implements Character, Weapon {
public void attack() {
System.out.println("Mage attacks with a wand.");
}
public void use() {
System.out.println("Mage uses a wand.");
}
}
public class Main {
public static void main(String[] args) {
Warrior warrior = new Warrior();
Mage mage = new Mage();
warrior.attack();
warrior.use();
mage.attack();
mage.use();
}
}
Polymorphism
Polymorphism is an Object-Oriented Programming (OOP) concept that allows a single action or method to behave in different ways. It enables the same method name to perform different tasks depending on:
- The object that calls it
- The parameters passed to it
The word polymorphism is derived from two Greek words:
- Poly → many
- Morphs → forms
So, polymorphism means “many forms.”
Types of Polymorphism in Java
Java supports two types of polymorphism:
- Compile-time Polymorphism
- Runtime Polymorphism
Polymorphism in Java is achieved using:
- Method Overloading
- Method Overriding
1. Compile-Time Polymorphism (Static Polymorphism)
Compile-time polymorphism is achieved using method overloading.
Key Points:
- Same method name
- Different parameter list (number, type, or order)
- Decision is made at compile time by the compiler
- Also called early binding
The compiler selects the correct method based on the arguments provided. If an exact match is found, it is executed; otherwise, type promotion is applied to find the closest match.
2. Runtime Polymorphism (Dynamic Method Dispatch)
Runtime polymorphism is also known as Dynamic Method Dispatch.
Key Points:
- Achieved using method overriding
- Method call is resolved at runtime
- Uses inheritance
- A superclass reference points to a subclass object
The method that executes depends on the actual object, not the reference type.
Note: Upcasting
Before runtime polymorphism, upcasting is used where a parent class reference refers to a child class object. This enables dynamic method dispatch.
Advantages of Polymorphism in Java
1. Code Reusability
Subclasses can reuse and override superclass methods, reducing code duplication.
2. Flexibility and Extensibility
New features can be added without modifying existing code.
3. Dynamic Method Invocation
Method execution is decided at runtime based on the actual object.
4. Interface Implementation
Different classes can implement the same interface in different ways, enabling flexible design.
5. Method Overloading Support
Same method name with different parameters improves readability and usability.
6. Reduced Code Complexity
Helps in building structured, modular, and maintainable applications.
Example
Compile-Time Polymorphism Example (Method Overloading)
class Calculation {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculation calc = new Calculation();
System.out.println("Sum of integers: " + calc.add(5, 3));
System.out.println("Sum of doubles: " + calc.add(2.5, 3.7));
}
}
Runtime Polymorphism Example (Method Overriding + Upcasting)
class Bike {
void run() {
System.out.println("running");
}
}
class Splendor extends Bike {
void run() {
System.out.println("running safely with 60km");
}
}
public class Main {
public static void main(String args[]) {
Bike b = new Splendor(); // upcasting
b.run();
}
}
Abstraction
Abstraction is an Object-Oriented Programming (OOP) concept that focuses on hiding implementation details and showing only the essential features to the user.
In simple words, abstraction means:
- Showing what an object does
- Hiding how it does it
Real-Life Example
When you send an SMS:
- You type the message and press send
- You do NOT know how the message is delivered internally
This is abstraction because the internal process is hidden.
Abstract Class in Java
An abstract class is a class that is declared using the abstract keyword.
It is used to achieve partial abstraction in Java.
An abstract class can contain:
- Abstract methods (without body)
- Non-abstract methods (with body)
Key Features of Abstract Class
1. Partial Abstraction
- It provides both complete and incomplete methods
2. Cannot Be Instantiated
- You cannot create an object of an abstract class
3. Used as a Base Class
- It is meant to be inherited by child classes
4. Method Implementation
- Child classes must implement abstract methods
Definition of Abstract Method
An abstract method is a method that:
- Has no body
- Must be implemented in the subclass
Important Points to Remember
- An abstract class must be declared using the abstract keyword
- It can contain abstract and non-abstract methods
- It cannot be instantiated (no object creation)
- It can have constructors
- It can also have static methods
- It is mainly used for code reusability and structure
Why Use Abstraction?
- To hide internal implementation details
- To reduce complexity
- To improve security
- To achieve better code organization
- To provide a clear structure for large applications
In Short
Abstraction in Java helps in hiding implementation details and showing only the important functionality, while abstract classes provide a way to achieve this by combining abstract and concrete methods.
Encapsulation
Encapsulation is the process of wrapping data (variables) and methods (functions) together into a single unit (class).
A simple real-life example of encapsulation is a capsule, which contains medicine inside it. The internal medicine is hidden, and we only use it as a whole unit.
How Encapsulation Works
To achieve encapsulation in Java:
- Declare all data members as private
- Provide public getter and setter methods
- Control access to data through these methods
This ensures that:
- Data is hidden from direct access
- Data is accessed in a controlled way
- Data is protected from unwanted modification
Fully Encapsulated Class
A class is called a fully encapsulated class when:
- All variables are declared as private
- Access is provided only through getter and setter methods
Encapsulation
Encapsulation in Java is an important Object-Oriented Programming (OOP) concept that helps in protecting data and restricting direct access to class members. It is mainly used to achieve data security and controlled access.
How Encapsulation Works
To achieve encapsulation in Java:
- Declare all data members as private
- Provide public getter and setter methods
- Control access to data through these methods
This ensures that:
- Data is hidden from direct access
- Data is accessed in a controlled way
- Data is protected from unwanted modification
Fully Encapsulated Class
A class is called a fully encapsulated class when:
- All variables are declared as private
- Access is provided only through getter and setter methods
Why Use Encapsulation in Java?
Encapsulation is used for several important reasons:
1. Data Protection
Encapsulation protects data from unauthorized access and modification.
2. Controlled Access
It allows controlled access to data using getter and setter methods.
3. Security
Sensitive data is hidden from direct access, improving application security.
4. Data Hiding
It hides internal implementation details and only shows necessary functionality.
5. Flexibility and Maintenance
Internal code can be changed without affecting other parts of the program.
6. Easy to Scale
Encapsulation makes applications easier to extend and maintain in large projects.
Example
class Student {
// private data members (data hiding)
private int id;
private String name;
// getter method for id
public int getId() {
return id;
}
// setter method for id
public void setId(int id) {
this.id = id;
}
// getter method for name
public String getName() {
return name;
}
// setter method for name
public void setName(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student();
// setting values using setter methods
s.setId(101);
s.setName("Rahul");
// getting values using getter methods
System.out.println("Student ID: " + s.getId());
System.out.println("Student Name: " + s.getName());
}
}