Introduction to Object-Oriented Programming
Introduction to Object-Oriented Programming
The word object-oriented is the combination of two words i.e. object and oriented.
The dictionary meaning of the object is an article or entity that exists in the real
world. The meaning of oriented is interested in a particular kind of thing or entity. In
layman's terms, it is a programming pattern that rounds around an object or entity are
called object-oriented programming.
Object-Oriented Programming or OOP refers to languages that use objects in
programming. Object-oriented programming aims to implement real-world entities like
inheritance, hiding, polymorphism, etc in programming. The main aim of OOP is to
bind together the data and the functions that operate on them so that no other part of
the code can access this data except that function.
It is the most popular programming model among developers. It is well suited for
programs that are large, complex, and actively updated or maintained. It simplifies
software development and maintenance by providing major concepts such as
abstraction, inheritance, polymorphism, and encapsulation. These core concepts
support OOP.
Class: A blueprint for creating objects. A class encapsulates data for the object.
Object: An instance of a class. It represents an entity with state and behaviour.
Inheritance: A mechanism where one class inherits the fields and methods of
another class.
Polymorphism: The ability of different objects to respond, each in their own way,
to identical messages (or methods).
Encapsulation: The bundling of data and the methods that operate on that data
within one unit, typically a class.
Abstraction: The process of hiding the complex implementation details and
showing only the essential features of the object.
Principles of object-oriented programming:
These are the four main principles of the object-oriented programming
paradigm. Understanding them is essential to becoming a successful
programmer.
1. Encapsulation
2. Inheritance
3. Abstraction
4. Polymorphism
Encapsulation
Encapsulation is a mechanism that allows us to bind data and functions of a class into an
entity. It protects data and functions from outside interference and misuse. Therefore, it
also provides security. A class is the best example of encapsulation.
Inheritance
The concept allows us to inherit or acquire the properties of an existing class (parent
class) into a newly created class (child class). It is known as inheritance. It provides code
reusability.
Polymorphism
The word polymorphism is derived from the two words i.e. ploy and morphs. Poly means
many and morphs means forms. It allows us to create methods with the same name but
different method signatures. It allows the developer to create clean, sensible, readable,
and resilient code.
The above figure best describes the concepts of polymorphism. A person plays an employee
role in the office, father and husband role in the home.
Abstraction
Java is a programming language and a platform. Java is a high level, robust, object-
oriented and secure programming language.
Java was developed by “Sun Microsystems” (which is now the subsidiary of Oracle)
in the year 1995. James Gosling is known as the father of Java. Before Java, its name
was Oak. Since Oak was already a registered company, so James Gosling and his
team changed the name from Oak to Java.
Platform: Any hardware or software environment in which a program runs, is known
as a platform. Since Java has a runtime environment (JRE) and API, it is called a
platform.
Importance of Java
One of the essential reasons for Java's popularity is the cross-platform compatible and
built-in security. Java program can run on any machine with a Java Runtime
Environment (JRE) installed.
Programs operate on various computers. Java is used by many banks, manufacturers,
insurance organizations, utilities, and retailers. It is the reason that major industries
ruled by Java.
As a constantly evolving programming language, Java has undergone many changes
and updates since its initial release. Here are some of the most important ones:
· Java 1.0 (January 23, 1996)
· Java 1.1 (February 19, 1997)
· Java 2 (December 8, 1998)
· Java 3 (May 8, 2000)
· Java 4 (February 6, 2002)
· Java 5 (September 30, 2004)
· Java 6 (December 11, 2006)
· Java 7 (July 28, 2011)
· Java 8 (March 18, 2014)
· Java 9 (September 21, 2017)
· Java 10 (March 20, 2018)
· Java 11 (September 25, 2018)
· Java 12 (March 19, 2019)
· Java 13 (September 17, 2019)
· Java 14 (March 17, 2020)
· Java 15 (September 15, 2020)
· Java 16 (March 16, 2021)
· Java 17 (September 21, 2021)
Features of Java:
The primary objective of Java programming language creation was to make it portable,
simple and secure programming language. Apart from this, there are also some excellent
features which play an important role in the popularity of this language. The features of
Java are also known as Java buzzwords.
A list of the most important features of the Java language is given below.
1. Simple
2. Object Oriented
3. Platform Independent
4. [Link]
5. Portable
6. Robust
7. Secure
8. Dynamic
9. Distributed
10. Multi Threaded
11. Interpretive
12. High Performance
1. Simple: -
2. Object-Oriented:
3. Platform Independent:
5. Portable:
6. Robust:
7. Secure:
8. Distributed:
11. Interpretive:
12. HighPerformance:
First, the source ‘.java’ file is passed through the compiler, which then encodes
the source code into a machine-independent encoding, as Bytecode. The content
of each class contained in the source file is stored in a separate ‘.class’ file.
The class files generated by the compiler are independent of the machine or the
OS, which allows them to be run on any system. To run, the main class file (the
class that contains the method main) is passed to the JVM and then goes
through three main stages before the final machine code is executed.
These stages are: These states do include:
1. ClassLoader
2. Bytecode Verifier
3. Just-In-Time Compiler
What is Java Bytecode?
Java bytecode is the instruction set for the Java Virtual Machine. It acts similar to
an assembler which is an alias representation of a C++ code.
As soon as a java program is compiled, java bytecode is generated. In more apt
terms, java bytecode is the machine code in the form of a .class file. With the help
of java bytecode we achieve platform independence in java.
When we write a program in Java, firstly, the compiler compiles that program and
a bytecode is generated for that piece of code.
When we wish to run this .class file on any other platform, we can do so. After the
first compilation, the bytecode generated is now run by the Java Virtual Machine
and not the processor in consideration.
This essentially means that we only need to have basic java installation on any
platforms that we want to run our code on.
Resources required to run the bytecode are made available by theJava Virtual
Machine, which calls the processor to allocate the required resources. JVM's are
stack-based so they stack implementation to read the codes.
JDK:
JDK is an acronym for Java Development Kit. The Java Development Kit (JDK)
is a software development environment which is used to develop Java
applications and applets. It physically exists. It contains JRE + development tools.
JDK is an implementation of any one of the below given Java Platforms released
by Oracle Corporation:
o Standard Edition Java Platform
o Enterprise Edition Java Platform
o Micro Edition Java Platform
The JDK contains a private Java Virtual Machine (JVM) and a few other
resources such as an interpreter/loader (java), a compiler (javac), an archiver (jar),
a documentation generator (Javadoc), etc. to complete the development of a Java
Application.
JRE:
JRE is an acronym for Java Runtime Environment. It is also written as Java RTE.
The Java Runtime Environment is a set of software tools which are used for
developing Java applications. It is used to provide the runtime environment. It is the
implementation of JVM. It physically exists. It contains a set of libraries + other
files that JVM uses at runtime.
The implementation of JVM is also actively released by other companies besides
Sun Microsystems.
JVM:
What it does?
The JVM performs following operation:
• Loads code
• Verifies code
• Executes code
• Provides runtime environment
JVM provides definitions for the:
• Memory area
• Class file format
• Register set
• Garbage-collected heap
• Fatal error reporting etc.
Install JAVA Software:
Step3: Scroll a little down there and find the option “Java” under “Hardware and Software”
and click on it
Step12: Open Search Bar and search for cmd and click on Enter.
Step13: Type “java --version” (to get to know the version of JDK) and press enter.
Java programs are composed of various elements called tokens. These include:
Keywords: Reserved words that have special meaning in Java (e.g., class, public,
static).
Identifiers: Names given to elements in the program such as classes,
methods, variables (e.g., HelloWorld, main).
Literals: Constant values used in the program (e.g., "Hello, World!", 100).
Operators: Symbols that perform operations on variables and values (e.g., +, -, *, /).
Separators: Symbols that help define structure (e.g., ;, {}, ()).
Keywords:
A name in Java program is called identifier, which can be used for identification
purpose. It can be method name, variable name, class name or label name.
Example:
class
Test
{
int number=10; int
Number=20;
int NUMBER=20; we can differentiate with case. int NuMbEr=30;
}
• Keywords for datatypes(8): byte, short, int, long, float, double, boolean, char
• Keywords for flow control(11): if, else, switch, case, default, while, do, for, break,
continue, return
• Keywords for modifiers(11): public, private, protected, static, final, abstract,
synchronized, native, strictfp
• Keywords for exception handling(6): try, catch, finally, throw, throws, assert
• Class related keywords(6): class, interface, extends, implements, package, import
• Object related keywords(4): new, instanceof, super,this
• void return type keyword(1): In Java, return type is mandatory. If a method won’t return
anything then we have to declare that method with void return type. But in C
language, return type is optional and default return type is optional.
• Unused keywords(2):
goto: Usage of goto created several problems in old languages, and SUN people banned this
keyword.
const: Use final instead of const.
Note: goto and const are unused keywords and if we are trying to use we will get
compile time error.
• Reserved literals(3): true, false values for Boolean data type, null is default value
for object reference.
• Enum keyword(1): We can use enum to define a group of named constants. Ex:
enum month={JAN,FEB…DEC};
Java Statements:
Java allows passing arguments to the main method via the command line.
These arguments are stored in the args array.
import [Link];
public class UserInputExample
{
public static void main(String[] args)
{ Scanner scanner = new
Scanner([Link]);
[Link]("Enter your name:");
String name = [Link]();
[Link]("Hello, " + name);
[Link]();
}
}
Escape Sequences
Escape sequences are used to represent certain special characters within string literals, such
as:
\n : New line
\t : Tab
\\ : Backslash
\" : Double quote
Comments
Comments are used to annotate code and are ignored by the compiler. They can be:
Programming Style
Good programming style involves writing clear, readable, and maintainable code. Key points
include:
Variable:
o local variable
o instance variable
o static variable
1. Local Variable :
A variable declared inside the body of the method is called local variable. You
can use this variable only within that method and the other methods in the class
aren't even aware that the variable exists.
A local variable cannot be defined with "static" keyword.
2. Instance Variable:
A variable declared inside the class but outside the body of the method, is called
an instance variable. It is not declared as static.
It is called an instance variable because its value is instance-specific and is not
shared among instances.
3. Static variable:
A variable that is declared as static is called a static variable. It cannot be local.
You can create a single copy of the static variable and share it among all the
instances of the class. Memory allocation for static variables happens only once
when the class is loaded in the memory.
Example to understand the types of variables in java
public class A
{
static int m=500;//static variable void
method()
{
int n=10;//local variable
}
public static void main(String args[])
{
int data=40;//instance variable
}
}//end of class
1. Instance Variables
A variable which is declared inside a class and outside all the methods and
blocks is an instance variable.
The general scope of an instance variable is throughout the class except in
static methods.
The lifetime of an instance variable is until the object stays in memory.
2. Class Variables
A variable which is declared inside a class, outside all the blocks and is
marked static is known as a class variable.
The general scope of a class variable is throughout the class.
The lifetime of a class variable is until the end of the program or as long as the
class is loaded in memory.
3. Local Variables
All other variables which are not instance and class variables are treated as
local variables including the parameters in a method.
Scope of a local variable is within the block in which it is declared.
The lifetime of a local variable is until the control leaves the block in which it
is declared.
Data Types in Java
Data types specify the different sizes and values that can be stored in the variable. There are
two types of data types in Java:
1. Primitive data types: The primitive data types include boolean, char, byte, short,
int, long, float and double.
2. Non-primitive data types: The non-primitive data types include Classes,
Interfaces, and Arrays.
The Boolean data type is used to store only two possible values: true and false.
This data type is used for simple flags that track true/false conditions.
The Boolean data type specifies one bit of information, but its "size" can't be
defined precisely.
Example: Boolean one = false
Byte Data Type
The byte data type is an example of primitive data type. It isan 8 -bit signed two's
complement integer. Its value-range lies between -128 to 127 (inclusive). Its
minimum value is -128 and maximum value is 127. Its default value is 0.
The byte data type is used to save memory in large arrays where the memory savings
is most required. It saves space because a byte is 4 times smaller than an integer. It
can also be used in place of "int" data type.
Example: byte a = 10, byte b = -20
The short data type is a 16-bit signed two's complement integer. Its value-range lies
between 32,768 to 32,767 (inclusive). Its minimum value is -32,768 and maximum
value is 32,767. Its default value is 0.
The short data type can also be used to save memory just like byte data type. A short
data type is 2 times smaller than an integer.
Example: short s = 10000, short r = -5000
The int data type is a 32-bit signed two's complement integer. Its value-range lies
between - 2,147,483,648 (-2^31) to 2,147,483,647 (2^31 -1) (inclusive). Its minimum
value is - 2,147,483,648and maximum value is 2,147,483,647. Its default value is 0.
The int data type is generally used as a default data type for integral values unless if
there is no problem about memory.
Example: int a = 100000, int b = -200000
The long data type is a 64-bit two's complement integer. Its value-range lies between
-9,223,372,036,854,775,808(-2^63) to 9,223,372,036,854,775,807(2^63 -1)
(inclusive).
Its minimum value is -9,223,372,036,854,775,808 and maximum value is
9,223,372,036,854,775,807. Its default value is 0. The long data type is used when
you need a range of values more than those provided by int.
Example: long a = 100000L, long b = -200000L
Float Data Type
The float data type is a single-precision 32-bit IEEE 754 floating [Link] value range
is unlimited. It is recommended to use a float (instead of double) if you need to save
memory in large arrays of floating point numbers.
The float data type should never be used for precise values, such as currency. Its
default value is 0.0F.
Example: float f1 = 234.5f
The double data type is a double-precision 64-bit IEEE 754 floating point. Its value
range is unlimited. The double data type is generally used for decimal values just like
float.
The double data type also should never be used for precise values, such as currency.
Its default value is 0.0d.
Example: double d1 = 12.3
In Java, type casting is a method or process that converts a data type into another
data type in both ways manually and automatically.
The automatic conversion is done by the compiler and manual conversion
performed by the programmer.
Type casting Convert a value from one data type to another data type is known as
type casting.
Types of Type Casting - There are two types of type casting:
o Widening Type Casting
o Narrowing Type Casting
1. Widening Type Casting :
Converting a lower data type into a higher one is called widening type casting. It
is also known as implicit conversion or casting down. It is done automatically. It
is safe because there is no chance to lose data. It takes place when:
Both data types must be compatible with each other.
The target type must be larger than the source type.
byte -> short -> char -> int -> long -> float -> double
For example, the conversion between numeric data type to char or Boolean is not
done automatically. Also, the char and Boolean data types are not compatible
with each other. Let's see an example.
[Link]
In the above example, we have taken a variable x and converted it into a long
type. After that, the long type is converted into the float type.
Converting a higher data type into a lower one is called narrowing type casting. It
is also known as explicit conversion or casting up.
It is done manually by the programmer.
If we do not perform casting then the compiler reports a compile-time
error. double -> float -> long -> int -> char -> short -> byte
Literal Constants:
Literal constants represent fixed values that are directly assigned to variables in the code. They are of
the following types:
Symbolic Constants:
Symbolic constants in Java are constants that are declared using the `final`
keyword. Once a `final` variable is assigned a value, it cannot be changed.
They are often used to represent fixed values that should not change during the
execution of a program.
The `printf()` method in Java is used for formatted output, providing more control
over the format of the output string.
It is particularly useful for printing formatted text, numbers, and other data types.
Format Specifiers: Used within the format string to denote the type of data being formatted.
- `%d`: Decimal integer
- `%f`: Floating-point number
- `%s`: String
- `%c`: Character
- `%n`: New line
Example:
int age = 25;
double salary = 50000.75;
String name = "John";
[Link]("Name: %s, Age: %d, Salary: %.2f%n", name, age, salary);
Static Variables and Methods:
1. Static Variables:
- Declared using the `static` keyword.
- Shared across all instances of a class.
- Can be accessed directly using the class name without creating an object.
2. Static Methods:
- Also declared using the `static` keyword.
- Can access only static variables and other static methods directly.
- Useful for utility or helper methods that do not depend on instance variables.
Example:
class MyClass {
static int staticVar = 10; // Static variable
static void display() { // Static method
[Link]("Static Variable: " + staticVar);
}
}
Attribute `final`:
The `final` keyword in Java is used to define constants. A `final` variable's value cannot be
modified once it is assigned. It can be applied to variables, methods, and classes:
1. Final Variables:
- The value assigned to a final variable cannot be changed.
- It must be initialized when declared or within the constructor if it's not a static
variable.
2. Final Methods:
- Cannot be overridden by subclasses.
Example: class Parent {
final void show() {
[Link]("This is a final method.");
}
}
3. Final Classes:
- Cannot be extended (inherited).
Operators in Java
Operator in Java is a symbol that is used to perform operations. For example: +, -, *, / etc.
There are many types of operators in Java which are given below:
Unary Operator,
Arithmetic Operator,
Shift Operator,
Relational Operator,
Bitwise Operator,
Logical Operator,
Ternary Operator and
Assignment Operator.
Java Unary Operator:
The Java unary operators require only one operand. Unary operators are used to perform
various operations i.e.:
incrementing/decrementing (a value by one)
negating an expression
inverting the value of a boolean
Java arithmetic operators are used to perform addition, subtraction, multiplication, and
division. They act as basic mathematical operations.
import [Link];
public class ArithmeticOperators
{ public static void main(String[]
args) { Scanner sc = new
Scanner([Link]);
[Link]("Enter the first number: ");
double num1 = [Link]();
[Link]("Enter the second number: ");
double num2 = [Link]();
double sum = num1 + num2;
double difference = num1 - num2;
double product = num1 * num2;
double quotient = num1 / num2;
[Link]("The sum of the two numbers is: " + sum);
[Link]("The difference of the two numbers is: " + difference);
[Link]("The product of the two numbers is: " + product);
[Link]("The quotient of the two numbers is: " + quotient);
}
}
Input:
Output:
The Java left shift operator << is used to shift all of the bits in a value to the left side of a
specified number of times.
The Java right shift operator >> is used to move the value of the left operand to right by the
number of bits specified by the right operand.
public OperatorExample {
public static void main(String args[]) {
[Link](10>>2);//10/2^2=10/4=2
[Link](20>>2);//20/2^2=20/4=5
[Link](20>>3);//20/2^3=20/8=2
}
}
• The logical && operator doesn't check the second condition if the first condition
is false. It checks the second condition only if the first one is true.
• The bitwise & operator always checks both conditions whether first condition is true
or false.
• The logical || operator doesn't check the second condition if the first condition is
true. It checks the second condition only if the first one is false.
• The bitwise | operator always checks both conditions whether first condition is true
or false.
Java Ternary operator is used as one line replacement for if-then-else statement and used a
lot in Java programming. It is the only conditional operator which takes three operands.
34 | P a g e By [Link] (Technical
Trainer)
Java Assignment Operator:
Java assignment operator is one of the most common operators. It is used to assign the value
on its right to the operand on its left. (=, +=, -=, *=, /=, %= )
import [Link].*;
class Assignment {
public static void main(String[] args) {
// Declaring variables
int num1 = 10, num2 = 20;
[Link]("num1 = " + num1);
//10 [Link]("num2 = " + num2);
//20
// Adding & Assigning values
num1 += num2;
// Displaying the assigned values
[Link]("num1 = " + num1); //30
}
}
35 | P a g e By [Link] (Technical
Trainer)
Unit-3
2. Loop statements
• do while loop
• while loop
• for loop
• for-each loop
3. Jump statements
• break statement
• continue statement
36 | P a g e By [Link] (Technical
Trainer)
Decision-Making statements:
• As the name suggests, decision-making statements decide which statement to
execute and when.
• Decision-making statements evaluate the Boolean expression and control the
program flow depending upon the result of the condition provided.
• There are two types, i.e., If statement and switch statement.
I. If Statement:
• In Java, the "if" statement is used to evaluate a condition.
• The control of the program is diverted depending upon the specific condition.
• The condition of the If statement gives a Boolean value, either true or false.
• In Java, there are four types of if-statements given below.
a. Simple if statement
b. if-else statement
c. if-else-if ladder
d. Nested if-statement
37 | P a g e By [Link] (Technical
Trainer)
Let's understand the if-statements one by one.
a) Simple if statement:
• It is the most basic statement among all control flow statements in Java.
• It evaluates a Boolean expression and enables the program to enter a block of code
if the expression evaluates to true.
Consider the following example in which we have used the if statement in the java code.
[Link]
public class Student {
public static void main(String[] args)
{ int x = 10;
int y = 12;
if(x+y > 20)
{
[Link]("x + y is greater than 20");
}
}
}
b) if-else statement
• The if-else statement is an extension to the if-statement, which uses another block
of code, i.e., else block.
• The else block is executed if the condition of the if-block is evaluated as false.
38 | P a g e By [Link] (Technical
Trainer)
Syntax:
if(condition) {
statement 1; //executes when condition is true
} else{
statement 2; //executes when condition is false
}
39 | P a g e By [Link] (Technical
Trainer)
c) if-else-if ladder:
• The if-else-if statement contains the if-statement followed by multiple else-if
statements.
• In other words, we can say that it is the chain of if-else statements that create a
decision tree where the program may enter in the block of code where the condition
is true.
• We can also define an else statement at the end of the chain.
41 | P a g e By [Link] (Technical
Trainer)
[Link]("city is noida");
}else if(city == "Agra") {
[Link]("city is agra");
}else {
[Link](city);
}
}
}
d) Nested if-statement
• In nested if-statements, the if statement can contain a if or if-else statement inside
another if or else-if statement.
42 | P a g e By [Link] (Technical
Trainer)
Consider the following example.
class Great { //Program that finds greatest among three number
public static void main(String args[]) {
int a=2,b=3,c=5;
if(a>b) {
if(a>c)
[Link](“a is greatest”);
else
[Link](“c is greatest”);
} else
{ if(b>c)
[Link](“b is greatest”);
else
[Link](“c is greatest”);
}
}
}
switch(grade) {
case 'A' :
44 | P a g e By [Link] (Technical
Trainer)
[Link]("Excellent!");
break;
case 'B' :
case 'C' :
[Link]("Well done");
break;
case 'D' :
[Link]("You passed");
case 'F' :
[Link]("Better try again");
break;
default :
[Link]("Invalid grade");
}
[Link]("Your grade is " + grade);
}
}
Loop Statements:
• In programming, sometimes we need to execute the block of code repeatedly
while some condition evaluates to true.
• However, loop statements are used to execute the set of instructions in a repeated order.
• The execution of the set of instructions depends upon a particular condition.
• In Java, we have three types of loops that execute similarly.
• However, there are differences in their syntax and condition checking time.
a) for loop
b) while loop
c) do-while loop
45 | P a g e By [Link] (Technical
Trainer)
a) Java for loop
In Java, for loop is similar to C and C++. It enables us to initialize the loop
variable, check the condition, and increment/decrement in a single line of code.
We use the for loop only when we exactly know the number of times, we want to
execute the block of code.
Consider the following example to understand the proper functioning of the for loop in
java, [Link]
public class Calculattion {
public static void main(String[] args) {
// TODO Auto-generated method stub int
sum = 0;
for(int j = 1; j<=10; j++)
{ sum = sum + j;
}
[Link]("The sum of first 10 natural numbers is " + sum);
}
}
46 | P a g e By [Link] (Technical
Trainer)
b) Java for-each loop
Java provides an enhanced for loop to traverse the data structures like array or
collection.
In the for-each loop, we don't need to update the loop variable.
Consider the following example to understand the functioning of the for-each loop in
Java. [Link]
public class Calculation {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] names = {"Java","C","C++","Python","JavaScript"};
[Link]("Printing the content of the array names:\
n"); for(String name:names) {
[Link](name);
} } }
47 | P a g e By [Link] (Technical
Trainer)
If the condition is true, then the loop body will be executed; otherwise, the
statements after the loop will be executed.
The flow chart for the while loop is given in the following image.
48 | P a g e By [Link] (Technical
Trainer)
The syntax of the do-while loop is given below.
do
{
//statements
} while (condition);
The flow chart of the do-while loop is given in the following image.
Consider the following example to understand the functioning of the do-while loop in
Java. [Link]
public class Calculation {
public static void main(String[] args) {
// TODO Auto-generated method stub int i
= 0;
[Link]("Printing the list of first 10 even numbers \n"); do
{
[Link](i); i =
i + 2;
}while(i<=10);
}
}
Jump Statements:
Jump statements are used to transfer the control of the program to the specific
statements.
In other words, jump statements transfer the execution control to the other part of
the program.
There are two types of jump statements in Java, i.e., break and continue.
49 | P a g e By [Link] (Technical
Trainer)
a) Java break statement
As the name suggests, the break statement is used to break the current flow of the
program and transfer the control to the next statement outside a loop or switch
statement.
However, it breaks only the inner loop in the case of the nested loop.
The break statement cannot be used independently in the Java program, i.e., it can
only be written inside the loop or switch statement.
The break statement example with for loop Consider the following example in which
we have used the break statement with the for loop. [Link]
50 | P a g e By [Link] (Technical
Trainer)
51 | P a g e By [Link] (Technical
Trainer)