gfgfgbfb
gfgfgbfb
Object-Oriented Programming (OOP) revolves around designing software based on real-world entities,
organizing them into objects that interact with one another. The four main pillars of OOP are:
1. Encapsulation
Encapsulation is the bundling of data (attributes) and methods (functions) that operate on the data into a single
unit, typically a class. Access to the internal details is restricted, which helps enforce a clear boundary
between an object’s internal state and its external interactions.
• Goal: Protect the integrity of the object and prevent unauthorized access or modification.
• Implementation:
o Use access specifiers such as private, protected, and public to control visibility.
o Provide getter and setter methods to allow controlled access to private variables.
Example:
class BankAccount {
return balance;
if (amount > 0) {
balance += amount;
2. Abstraction
Abstraction focuses on showing only the essential features of an object while hiding the underlying
implementation details. It simplifies the complexity of the system by only exposing the relevant aspects.
• Goal: Reduce complexity and increase efficiency by focusing on "what" an object does rather than
"how" it does it.
• Implementation:
o Use abstract classes and interfaces to define common functionality while leaving
implementation to derived classes.
Example:
abstract class Shape {
@Override
void draw() {
System.out.println("Drawing a circle");
3. Inheritance
Inheritance allows one class (child/subclass) to acquire the properties and behaviors of another class
(parent/superclass). It promotes code reuse and establishes a natural hierarchy between classes.
• Implementation: Use the extends keyword (in Java) or similar in other languages to inherit.
Example:
class Animal {
void eat() {
void bark() {
Usage:
dog.bark();
4. Polymorphism
Polymorphism allows objects to take on multiple forms. It enables a single interface or method to work in
different ways depending on the context, promoting flexibility and scalability.
• Goal: Allow a single interface or method to behave differently based on the object it operates on.
• Types:
▪ Multiple methods with the same name but different parameter lists.
Example (Overloading):
class Calculator {
return a + b;
return a + b;
Example (Overriding):
class Animal {
void sound() {
@Override
void sound() {
System.out.println("Meow");
Usage:
Friend Function
In C++, a friend function is a special function that is not a member of a class but has the right to access private
and protected members of that class. Declaring a function as a friend allows it to bypass the encapsulation
rules that normally restrict access to a class's internal details.
Key Points:
1. Declaration:
o A friend function is declared within the class using the friend keyword but is defined outside the
class.
o The declaration in the class simply tells the compiler that the function is a friend, not a member.
2. Access to Members:
o A friend function can access private and protected members of the class it is declared a friend
of.
3. Usage:
o It is commonly used for operator overloading, where the operator function needs access to
private members of a class.
o When two or more classes need to access each other's private or protected members.
Syntax:
#include <iostream>
class MyClass {
private:
int privateData;
public:
};
int main() {
MyClass obj(42);
return 0;
Output:
Private Data: 42
Characteristics:
o A friend function is not called using an object of the class. It is a standalone function.
o The function definition is typically outside the class unless it's a member of another class or a
part of the same file.
3. Two-Way Access:
o If a friend function of one class accesses another class's private data, that other class must
also explicitly declare it as a friend.
#include <iostream>
class MyClass {
private:
int value;
public:
MyClass(int v) : value(v) {}
int main() {
cout << "Result: " << result.value << endl; // Access private member directly is not possible
return 0;
Explanation:
• The operator+ is defined as a friend to access the private value of the MyClass objects.
Friend functions are a powerful feature but should be used judiciously to maintain proper encapsulation and
avoid breaking the design principles of object-oriented programming.
Constructors
Here’s a concise explanation of the default constructor, parameterized constructor, copy constructor, and
assignment operator constructor in C++:
1. Default Constructor
Example:
class MyClass {
public:
int x;
};
• Definition: A constructor that takes arguments to initialize objects with specific values.
Example:
class MyClass {
public:
int x;
x = value;
};
3. Copy Constructor
• Purpose: Used for deep copying or when objects are passed by value.
• Compiler-Provided Copy Constructor: If not explicitly defined, the compiler generates a default one
that performs a shallow copy.
Example:
class MyClass {
public:
int x;
};
• Definition: Not a constructor, but an operator (operator=) that assigns values from one object to
another.
• Purpose: Used for assigning one existing object to another of the same class.
• Difference from Copy Constructor: The copy constructor initializes a new object, while the
assignment operator updates an existing object.
• Compiler-Provided Assignment Operator: If not explicitly defined, the compiler generates a shallow
copy implementation.
Example:
class MyClass {
public:
int x;
x = obj.x;
return *this;
};
Summary Table:
Default Constructor Initializes objects with defaults Object is created without arguments.
Parameterized Constructor Initializes objects with custom Object is created with arguments.
values
Assignment Constructor Assigns values to an existing = operator is used between two existing
(Operator) object objects.
UNIT 2
In C++, runtime polymorphism and compile-time polymorphism are two forms of polymorphism that allow
functions or methods to behave differently based on their usage. Here's a detailed explanation of both:
1. Compile-time Polymorphism
Compile-time polymorphism, also known as early binding, happens when the function call is resolved at
compile time. This is achieved through:
• Function Overloading: Multiple functions with the same name but different parameter lists.
• Operator Overloading: Defining custom behavior for operators for user-defined types.
Characteristics:
• Limited flexibility because the exact method to call must be known at compile time.
#include <iostream>
class Calculator {
public:
return a + b;
return a + b;
};
int main() {
Calculator calc;
cout << "Integer addition: " << calc.add(5, 3) << endl; // Calls add(int, int)
cout << "Double addition: " << calc.add(2.5, 3.1) << endl; // Calls add(double, double)
return 0;
#include <iostream>
public:
// Overloading + operator
void display() {
cout << real << " + " << imag << "i" << endl;
};
int main() {
c3.display();
return 0;
2. Runtime Polymorphism
Runtime polymorphism, also known as late binding, occurs when the function call is resolved at runtime. This
is achieved through:
• Function Overriding: A derived class provides a specific implementation of a virtual function defined in
the base class.
• Virtual Functions: Functions marked with the virtual keyword in the base class to enable late binding.
Characteristics:
• Provides flexibility because the exact method to call depends on the actual type of the object at
runtime.
class Animal {
public:
};
public:
};
public:
};
int main() {
Dog dog;
Cat cat;
animal = &dog;
animal = &cat;
animal->sound(); // Calls Cat's sound()
return 0;
Key Points:
• Without the virtual keyword, the method of the base class would always be called, regardless of the
object type.
Performance Faster due to early binding Slightly slower due to late binding (vtable
lookup)
By combining these forms, C++ supports both performance and flexibility, catering to different programming
needs.
UNIT 3
Inheritance
Inheritance in C++ is a mechanism that allows one class (called the derived class) to inherit properties and
behavior (data members and member functions) from another class (called the base class). This promotes
code reuse and establishes a relationship between classes. There are several types of inheritance in C++, each
serving a specific purpose. Here's an overview:
1. Single Inheritance
• Example:
class Base {
public:
void show() {
cout << "Base class" << endl;
}
};
• Use Case: Useful when there is a straightforward relationship between two classes.
2. Multiple Inheritance
• Example:
class Base1 {
public:
void show() {
cout << "Base1 class" << endl;
}
};
class Base2 {
public:
void display() {
cout << "Base2 class" << endl;
}
};
3. Multilevel Inheritance
• Example:
class Base {
public:
void show() {
cout << "Base class" << endl;
}
};
4. Hierarchical Inheritance
• Example:
class Base {
public:
void show() {
cout << "Base class" << endl;
}
};
• Definition: A combination of multiple and multilevel inheritance to avoid duplication of data from the
base class.
When inheriting a class, the access specifier (public, protected, or private) determines how the base class
members are inherited:
• Public inheritance: Public and protected members of the base class remain public and protected in
the derived class.
• Protected inheritance: Public and protected members of the base class become protected in the
derived class.
• Private inheritance: Public and protected members of the base class become private in the derived
class.
Understanding the appropriate type of inheritance to use is essential for designing efficient and maintainable
object-oriented systems in C++.
Generic Programming
Generic programming in C++ is a programming paradigm that allows developers to write flexible, reusable, and
type-independent code. This is achieved through the use of templates, which enable functions, classes, and
other constructs to work with any data type without being rewritten for each one.
1. Templates:
o It allows you to define a single implementation that can operate on different data types.
2. Function Templates:
Example:
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
std::cout << add(3, 4) << std::endl; // Works with integers
std::cout << add(3.5, 2.5) << std::endl; // Works with doubles
}
3. Class Templates:
o Used to define classes that can work with any data type.
o Example:
template <typename T>
class Box {
private:
T data;
public:
void setData(T d) { data = d; }
T getData() const { return data; }
};
int main() {
Box<int> intBox;
intBox.setData(42);
std::cout << intBox.getData() << std::endl;
Box<std::string> strBox;
strBox.setData("Hello");
std::cout << strBox.getData() << std::endl;
}
4. Template Specialization:
o Example:
template <typename T>
class Box {
public:
void display() { std::cout << "Generic Box" << std::endl; }
};
Box<int> intBox;
intBox.display(); // Outputs: Integer Box
}
o The STL is a collection of pre-written generic classes and functions such as containers (e.g.,
vector, list), algorithms (e.g., sort, find), and iterators.
6. Type Deduction:
o When you use a template, the compiler deduces the type automatically based on the provided
arguments, making the code cleaner and reducing the likelihood of errors.
Limitations
• Compilation Overhead: Templates can increase compilation time due to type expansion.
• Code Bloat: If not managed carefully, templates can lead to larger binary sizes as separate versions are
generated for different types.
Generic programming is one of the most powerful features of C++ and forms the backbone of the STL, making it
an essential concept for modern C++ programming.
UNIT 4
Platform Independence
Platform independence means that Java programs can run on any operating system (Windows, macOS, Linux,
etc.) without needing recompilation. This is achieved through:
1. Compilation to Bytecode:
o When Java source code is compiled, it is converted into an intermediate, platform-neutral form
called bytecode. This bytecode is not specific to any particular operating system or hardware.
o The JVM acts as an interpreter for the bytecode. Each operating system has its own
implementation of the JVM, which translates the bytecode into machine code specific to that
platform at runtime. Since the JVM abstracts the underlying operating system, the same Java
bytecode can run on any platform where a JVM is available.
Key Point: Write Once, Run Anywhere (WORA) — Developers write Java code once, and it can run on any
platform with a JVM.
Architecture Independence
Architecture independence means that Java programs are not tied to the specific hardware architecture (like
x86, ARM, etc.) of the system they run on. This is made possible because:
1. Hardware-Agnostic Bytecode:
o The bytecode generated by the Java compiler does not depend on the underlying processor
architecture. It is designed to be neutral to factors such as instruction sets and register
configurations.
2. JVM as a Mediator:
Input datatype
import java.util.Scanner;
System.out.println("\nYou entered:");
System.out.println("Integer: " + intValue);
System.out.println("Float: " + floatValue);
System.out.println("Double: " + doubleValue);
System.out.println("Boolean: " + booleanValue);
System.out.println("Word: " + word);
System.out.println("Character: " + charValue);
System.out.println("Sentence: " + sentence);
scanner.close();
}
}
Here’s an explanation of the keywords static, final, and super in Java, along with examples for each:
1. static
The static keyword is used to declare members (variables, methods, or blocks) that belong to the class rather
than to any specific instance of the class.
Characteristics:
Example:
class StaticExample {
static int count = 0; // Static variable
StaticExample() {
count++; // Increment the static variable
}
2. final
The final keyword is used to declare constants, prevent method overriding, and prevent inheritance.
Usage:
Example:
class FinalExample {
final int MAX_VALUE = 100; // Final variable
3. super
The super keyword refers to the immediate parent class and is used to:
Example:
class Parent {
String message = "Hello from Parent";
void display() {
System.out.println("Parent Method");
}
}
void display() {
super.display(); // Call parent class's method
System.out.println(super.message); // Access parent class's variable
}
}
Summary Table:
static For members belonging to the class Shared across all instances; callable without creating
rather than instances. an object.
final To restrict modification. Used for constants, methods that can't be overridden,
or classes that can't be subclassed.
super To refer to the parent class. Access parent methods, variables, or constructor.
Interface in JAVA
In Java, an interface is a reference type, similar to a class, that is used to define a set of abstract methods
(methods without implementation) and constants. An interface provides a way to achieve abstraction and
multiple inheritance in Java. It is one of the key features that supports the Object-Oriented Programming (OOP)
principles of Java.
1. Pure Abstraction:
o An interface is a blueprint for a class and defines what a class must do, but not how it does it.
o It contains only method declarations (by default, abstract methods) and constant variables
(declared with final).
2. Method Implementation:
o Interfaces cannot contain method bodies for abstract methods (before Java 8).
3. No Constructors:
o A class can implement multiple interfaces, enabling a form of multiple inheritance that Java
classes do not support directly.
5. Public Methods:
o Methods in an interface are implicitly public and abstract (unless they are default or static).
6. Variables in Interfaces:
Syntax of an Interface
Implementing an Interface
A class must use the implements keyword to use an interface and provide implementations for all of its
abstract methods.
// Implementing the interface
class Dog implements Animal {
// Providing implementation for abstract method
public void sound() {
System.out.println("The dog barks.");
}
}
// Main class to test the implementation
public class Main {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.sound(); // Output: The dog barks.
myDog.eat(); // Output: This animal eats food.
A class can implement multiple interfaces, providing a way to achieve multiple inheritance.
interface Printable {
void print();
}
interface Showable {
void show();
}
Advantages of Interfaces
2. Standardization: Ensures consistent method signatures across classes that implement the same
interface.
3. Abstraction: Provides a way to define contracts that multiple classes must adhere to.
1. Defining Contracts:
o Interfaces are commonly used to define contracts or APIs between different modules of a
system.
2. Plug-and-Play:
o Interfaces allow objects to be interchangeable if they implement the same interface, making the
code flexible.
3. Marker Interfaces:
o Empty interfaces like Serializable or Cloneable are used to signal or mark classes for special
behavior.
Summary
• From Java 8 onward, interfaces can include default and static methods.
• They play a crucial role in designing reusable, scalable, and maintainable systems.
1. Definition: A class that cannot be instantiated directly. It is meant to serve as a base class for other
classes.
2. Purpose: Provides a common structure and functionality that can be shared across multiple
subclasses, while also leaving certain details to be implemented by the subclasses.
3. Characteristics:
o It can contain abstract methods (methods without a body).
4. Use Case: When you want to provide a template for a group of related classes and ensure they
implement specific methods.
Syntax:
abstract class Animal {
// Abstract method (no body)
abstract void makeSound();
Abstract Method
1. Definition: A method that is declared without an implementation (no method body) and is intended to
be overridden in subclasses.
2. Purpose: Ensures that all subclasses provide their specific implementation for the method.
3. Characteristics:
Syntax:
abstract class Animal {
// Abstract method
abstract void makeSound();
}
Key Points
4. Abstract classes can have constructors, but they are called only when instantiated through a subclass.
Example
abstract class Shape {
// Abstract method
abstract void draw();
// Concrete method
void info() {
System.out.println("This is a shape.");
}
}
This demonstrates how abstract classes and methods enforce a contract while allowing flexibility in
implementation.
Definition A reference type that can contain A class that can have both abstract
abstract methods, default methods, methods (without implementation) and
static methods, and constants. concrete methods (with implementation).
Purpose Used to define a contract or a set of Used to represent a base class that
methods that implementing classes provides partial implementation and
must adhere to. forces subclasses to complete the rest.
Keyword Used Declared using the interface keyword. Declared using the abstract keyword.
Method - Only default, static, or private methods - Can have both abstract and fully
Implementation can have implementations. implemented methods.
Multiple A class can implement multiple A class can extend only one abstract class
Inheritance interfaces. (single inheritance).
Constructors Interfaces cannot have constructors Abstract classes can have constructors to
because they cannot be instantiated. initialize common fields for subclasses.
Access Modifiers Methods are implicitly public. Methods can have any access modifier
(public, protected, private).
Variables - Variables are implicitly public, static, - Can have instance variables (non-final,
and final (constants). static, or final).
Use Case Ideal for defining capabilities (e.g., Ideal for defining inheritance hierarchies
Flyable, Readable, etc.). or partial implementations.
Inheritance Type Allows achieving multiple inheritance Does not support multiple inheritance
because a class can implement multiple because a class can extend only one
interfaces. abstract class.
Default and Static Supported (introduced in Java 8). Not specifically supported, but methods
Methods in abstract classes can have
implementations.
Performance Interfaces require more work for the JVM Abstract classes are slightly faster
to resolve methods at runtime, as they because method calls are resolved
rely on dynamic method lookup. statically at compile time when possible.
• If you want to provide a contract or behavior that multiple classes should follow.
Example:
interface Flyable {
void fly();
}
interface Movable {
void move();
}
• If you want to provide a base class with some common functionality while forcing subclasses to
implement specific methods.
Example:
abstract class Animal {
abstract void sound();
void eat() {
System.out.println("This animal eats food.");
}
}
Summary
• Use abstract classes for creating a base class with partial implementation and when sharing common
behaviour is required.
Generic programming in Java allows you to write classes, interfaces, and methods that can operate on any
data type while ensuring type safety. This is achieved using generics, which were introduced in Java 5 as
part of the Java Collections Framework (JCF).
1. Type Safety: Ensures that only the specified type of data can be used, reducing runtime errors.
Generic Classes
A generic class is a class that can operate on any data type specified when the class is instantiated.
Syntax:
class ClassName<T> {
Example:
private T data;
public void setData(T data) {
this.data = data;
public T getData() {
return data;
intBox.setData(123);
strBox.setData("Hello Generics");
Key Points:
• The type parameter (T) is replaced with the actual type when the object is created.
Generic Methods
A generic method is a method that can be declared within a generic or non-generic class and works with
any data type.
Syntax:
// Method body
Example:
System.out.println();
printArray(intArray);
printArray(strArray);
Key Points:
• The <T> before the return type indicates that this method is generic.
Generic Interfaces
Generic interfaces allow the definition of type parameters at the interface level.
Example:
K getKey();
V getValue();
private K key;
private V value;
this.key = key;
this.value = value;
}
public K getKey() {
return key;
public V getValue() {
return value;
You can restrict the types that can be passed to a generic class, method, or interface using bounded type
parameters.
Syntax:
Example:
private T number;
this.number = number;
Wildcard in Generics
Wildcards allow greater flexibility when working with generics by representing an unknown type.
Syntax:
• Bounded Wildcards:
Example:
import java.util.*;
System.out.println();
printList(intList);
printList(strList);
2. Code Reusability: Write code once and reuse it for different types.
3. Elimination of Explicit Casting: Simplifies code by removing the need for casting.
Limitations of Generics
1. Type Erasure: Generics in Java are implemented using type erasure, meaning type information is
removed during runtime.
2. Primitive Types: Generics do not support primitive types directly (e.g., int, double); you must use
wrapper classes (Integer, Double).
Generics in Java make code more robust, readable, and efficient by encouraging the use of type-safe
programming practices.
UNIT 5
Exception Handling
Java provides a robust mechanism for handling exceptions to ensure a program can handle runtime errors
gracefully. Let’s understand each keyword in detail with examples.
1. try
o A single try block can have multiple catch blocks to handle different exceptions.
Example:
try {
int result = 10 / 0; // Division by zero causes ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Exception caught: " + e.getMessage());
}
2. catch
o It provides a way to deal with the error without halting the program.
• Example:
try {
String str = null;
System.out.println(str.length()); // NullPointerException
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException: " + e);
}
3. throw
o User can define its own conditions for occurrence of a pre-defined exception.
o When an exception is thrown, the flow of execution is interrupted, and it searches for the
nearest catch block.
• Example:
class Test {
static void checkAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or older.");
}
System.out.println("Access granted.");
}
}
o The throws keyword is used in a method declaration to indicate the exceptions that the method
can throw.
• Example:
import java.io.*;
class Test {
static void readFile() throws IOException {
FileReader file = new FileReader("nonexistent.txt");
}
}
5. finally
o The finally block is used to execute code regardless of whether an exception is thrown or
caught.
o It is typically used for resource cleanup (e.g., closing files, database connections).
o The finally block is optional but highly recommended for cleanup operations.
class Example {
static void processFile(String filename) throws IOException {
FileReader file = new FileReader(filename);
System.out.println("File opened successfully.");
}
try {
throw new ArithmeticException("Division by zero error.");
} catch (ArithmeticException e) {
System.out.println("Exception caught using throw: " +
e.getMessage());
}
}
}
Purpose Used to explicitly throw an exception. Declares exceptions a method can throw.
Type Creates and throws one specific Can declare multiple exceptions separated by
exception. commas.
Summary
MULTITHREADING
Multithreading in Java is a technique that allows a program to execute multiple threads simultaneously,
enabling parallel execution of tasks. This is particularly useful for making programs more efficient by utilizing
multiple CPU cores and improving the performance of applications that perform time-consuming or
independent tasks.
1. Thread:
o A thread is the smallest unit of a process. In Java, each thread runs independently but shares
the process's resources, such as memory and file handles.
o Threads in Java are represented by the Thread class in the java.lang package.
2. Multithreading:
3. Main Thread:
o Every Java program starts with a main thread, which is the thread responsible for executing the
main() method.
• Override the run() method to define the task for the thread.
• Override the run() method to define the task for the thread.
• Pass an instance of the class to a Thread object and start the thread.
class MyRunnable implements Runnable {
public void run() {
System.out.println("Thread is running");
}
}
Thread States
Threads in Java can be in one of the following states:
2. Runnable: The thread is ready to run but is waiting for CPU time.
4. Blocked/Waiting: The thread is waiting for a resource or another thread to complete its task.
5. Terminated: The thread has completed its task and is no longer active.
Synchronization
When multiple threads access shared resources, synchronization is necessary to prevent data inconsistency or
corruption. Java provides synchronized blocks and methods to achieve this.
class SharedResource {
System.out.print("[");
System.out.print(message);
System.out.println("]");
Thread Priorities
Threads in Java can have priorities ranging from 1 (MIN_PRIORITY) to 10 (MAX_PRIORITY). The default priority is
5 (NORM_PRIORITY). The JVM uses these priorities to decide thread scheduling.
thread.setPriority(Thread.MAX_PRIORITY);
Benefits of Multithreading
Challenges of Multithreading
By mastering multithreading, Java developers can build highly efficient, responsive, and concurrent
applications.