OBJECT ORIENTED PROGRAMMING
Object-Oriented Programming is a methodology or paradigm to design a program using classes and
objects. It simplifies the software development and maintenance by providing some concepts defined below:
Class is a user-defined data type which defines its properties and its functions. Class is the only logical
representation of the data. For example, Human being is a class. The body parts of a human being are its
properties, and the actions performed by the body parts are known as functions. The class does not occupy
any memory space till the time an object is instantiated.
Java Syntax (for class):
class Student {
public int id; // data member
public int mobile;
public String name;
public int add(int x, int y) { // member functions
return x + y;
}
}
Object is a run-time entity. It is an instance of the class. An object can represent a person, place or any other
item. An object can operate on both data members and member functions.
Java Syntax (for object):
Student s = new Student();
Note: When an object is created using a new keyword, then space is allocated for the variable in a heap, and
the starting address is stored in the stack memory. When an object is created without a new keyword, then
space is not allocated in the heap memory, and the object contains the null value in the stack.
Inheritance
Inheritance is a process in which one object acquires all the properties and behaviors of its parent object
automatically. In such a way, you can reuse, extend or modify the attributes and behaviors which are defined
in other classes.
In Java, the class which inherits the members of another class is called derived class and the class whose
members are inherited is called base class. The derived class is the specialized class for the base class.
Java Syntax:
class DerivedClass extends BaseClass {
// visibility-modes = {private, protected, public}
}
Simple Inheritance Examples in Java
1. Single Inheritance
class Animal {
void eat() {
[Link]("Eating");
}
}
class Dog extends Animal {
void bark() {
[Link]("Barking");
}
}
Word: Dog inherits from Animal
2. Multiple Inheritance (using interfaces)
Diamond Problem
What is it?
The diamond problem occurs when a class inherits from two classes that both inherit from the same parent
class, creating a diamond shape in the inheritance hierarchy.
Visual Diagram:
A
/\
B C
\/
D
The Problem:
If class D inherits from both B and C, and both B and C have inherited/overridden the same method from A,
which version should D use?
2. Multiple Inheritance (using interfaces)
interface A {
void showA();
}
interface B {
void showB();
}
class C implements A, B {
public void showA() {
[Link]("A");
}
public void showB() {
[Link]("B");
}
}
Word: C inherits from both A and B
3. Hierarchical Inheritance
class Parent {
void show() {
[Link]("Parent");
}
}
class Child1 extends Parent {
}
class Child2 extends Parent {
}
Word: Child1 and Child2 both inherit from Parent
4. Multilevel Inheritance
class A {
void showA() {
[Link]("A");
}
}
class B extends A {
void showB() {
[Link]("B");
}
}
class C extends B {
void showC() {
[Link]("C");
}
}
Word: C inherits from B, B inherits from A (chain)
5. Hybrid Inheritance
class A {
void showA() {
[Link]("A");
}
}
interface B {
void showB();
}
class C extends A implements B {
public void showB() {
[Link]("B");
}
}
Word: C inherits from class A and interface B (combination)
Encapsulation
Encapsulation is the process of combining data and functions into a single unit called class. In
Encapsulation, the data is not accessed directly; it is accessed through the functions present inside the class.
In simpler words, attributes of the class are kept private and public getter and setter methods are provided to
manipulate these attributes. Thus, encapsulation makes the concept of data hiding possible. (Data hiding: a
language feature to restrict access to members of an object, reducing the negative effect due to
dependencies. e.g. "protected", "private" feature in Java).
Abstraction
We try to obtain an abstract view, model or structure of a real life problem, and reduce its unnecessary
details. With definition of properties of problems, including the data which are affected and the operations
which are identified, the model abstracted from problems can be a standard solution to this type of problems.
It is an efficient way since there are nebulous real-life problems that have similar properties.
Abstraction is the process of hiding implementation details and exposing only essential features to the
user, using abstract classes or interfaces.
Data binding: Data binding is a process of binding the application UI and business logic. Any change made
in the business logic will reflect directly to the application UI.
// Abstraction using abstract class
abstract class Payment {
abstract void pay(int amount);
void receipt() {
[Link]("Receipt generated");
}
}
// Concrete implementation 1
class UpiPayment extends Payment {
void pay(int amount) {
[Link]("Paid " + amount + " using UPI");
}
}
// Main class
public class AbstractionDemo {
public static void main(String[] args) {
// Reference of abstract class
Payment p;
p = new UpiPayment();
[Link](500);
[Link]();
}
}
Output
Paid 500 using UPI
Receipt generated
Polymorphism
Polymorphism is the ability to present the same interface for differing underlying forms (data types). With
polymorphism, each of these classes will have different underlying data. A point shape needs only two
coordinates (assuming it's in a two-dimensional space of course). A circle needs a center and radius. A
square or rectangle needs two coordinates for the top left and bottom right corners and (possibly) a rotation.
An irregular polygon needs a series of lines. Precisely, Poly means 'many' and morphism means 'forms'.
Types of Polymorphism (IMPORTANT)
1. Compile Time Polymorphism (Static)
2. Runtime Polymorphism (Dynamic)
Let's understand them one by one:
Compile Time Polymorphism: The polymorphism which is implemented at the compile time is known as
compile-time polymorphism. Example - Method Overloading
Method Overloading: Method overloading is a technique which allows you to have more than one function
with the same function name but with different functionality. Method overloading can be possible on the
following basis:
1. The return type of the overloaded function.
2. The type of the parameters passed to the function.
3. The number of parameters passed to the function.
Example:
class Add {
public int add(int a, int b) {
return (a + b);
}
public int add(int a, int b, int c) {
return (a + b + c);
}
}
public class Main {
public static void main(String[] args) {
Add obj = new Add();
int res1, res2;
res1 = [Link](2, 3);
res2 = [Link](2, 3, 4);
[Link](res1 + " " + res2);
}
}
/*
Output : 5 9
add() is an overloaded function with a different number of parameters.
*/
Runtime Polymorphism: Runtime polymorphism is also known as dynamic polymorphism. Function
overriding is an example of runtime polymorphism. Function overriding means when the child class
contains the method which is already present in the parent class. Hence, the child class overrides the method
of the parent class. In case of function overriding, parent and child classes both contain the same function
with a different definition. The call to the function is determined at runtime is known as runtime
polymorphism.
Java Sample Code:
class BaseClass {
public void show() {
[Link](" base");
}
}
class DerivedClass extends BaseClass {
@Override
public void show() {
[Link](" derived");
}
}
public class Main {
public static void main(String[] args) {
BaseClass b;
DerivedClass d = new DerivedClass();
b = d;
[Link](); // prints the content of show() declared in derived
class
}
}
// Output : derived
Constructor: Constructor is a special method which is invoked automatically at the time of object creation.
It is used to initialize the data members of new objects generally. The constructor in Java has the same name
as class or structure.
There can be three types of constructors in Java.
1. Default constructor: A constructor which has no argument is known as default constructor. It is
invoked at the time of creating an object.
2. Parameterized constructor: Constructor which has parameters is called a parameterized
constructor. It is used to provide different values to distinct objects.
3. Copy Constructor: A Copy constructor is an overloaded constructor used to declare and initialize
an object from another object. It is of two types - default copy constructor and user defined copy
constructor.
Java Sample Code:
class Go {
public int x;
Go(int a) { // parameterized constructor.
x = a;
}
Go(Go i) { // copy constructor
x = i.x;
}
}
public class Main {
public static void main(String[] args) {
Go a1 = new Go(20); // Calling the parameterized constructor.
Go a2 = new Go(a1); // Calling the copy constructor.
[Link](a2.x);
}
}
// Output : 20
Destructor: A destructor works opposite to constructor; it destructs the objects of classes. It can be defined
only once in a class. Like constructors, it is invoked automatically. In Java, there is no destructor concept
like C++. Instead, Java uses garbage collection and finalize() method.
Example:
class A {
// constructor and finalize are called automatically,
// once the object is instantiated
A() {
[Link]("Constructor in use");
}
protected void finalize() {
[Link]("Destructor in use");
}
}
public class Main {
public static void main(String[] args) {
A a = new A();
A b = new A();
a = null;
b = null;
[Link](); // requesting garbage collection
}
}
/*
Output: Constructor in use
Constructor in use
Destructor in use
Destructor in use
*/
'this' Keyword: this is a keyword that refers to the current instance of the class. There can be 3 main uses of
'this' keyword:
1. It can be used to pass the current object as a parameter to another method
2. It can be used to refer to the current class instance variable.
3. It can be used to declare indexers.
Java Syntax:
class Node {
int data;
Node next;
Node(int x) {
[Link] = x;
[Link] = null;
}
}
Friend Function: In Java, there is no direct concept of friend function like C++. However, we can achieve
similar functionality using package-private access or by providing public getter/setter methods. Java's
approach is to use proper access modifiers and encapsulation.
Note:
1. In Java, methods in the same package can access package-private members.
2. Public methods can be used to provide controlled access to private members.
Example (IMPORTANT):
class A {
private int a = 2;
private int b = 4;
// public method to provide access
public int mul() {
return (this.a * this.b);
}
}
public class Main {
public static void main(String[] args) {
A obj = new A();
int res = [Link]();
[Link](res);
}
}
// Output : 8
Aggregation: It is a process in which one class defines another class as any entity reference. It is another
way to reuse the class. It is a form of association that represents the HAS-A relationship.
Virtual Function (IMPORTANT): In Java, all non-static methods are virtual by default. A virtual function
is used to replace the implementation provided by the base class. The replacement is always called whenever
the object in question is actually of the derived class, even if the object is accessed by a base reference rather
than a derived reference.
1. A virtual function is a member function which is present in the base class and redefined by the
derived class.
2. When we use the same function name in both base and derived class, the function in base class can
be overridden.
3. When the function is overridden, then Java determines at run-time which function is to be called
based on the type of the object pointed by the base class reference. Thus, by making the base class
reference to point to different objects, we can execute different versions of the virtual functions.
Key Points:
1. All methods in Java are virtual by default unless declared as static or final.
2. A class may not have a destructor but uses finalize() method and garbage collection.
Java Example:
class Base {
// virtual function (re-defined in the derived class)
public void print() {
[Link]("print base class");
}
public void show() {
[Link]("show base class");
}
}
class Derived extends Base {
@Override
public void print() {
[Link]("print derived class");
}
@Override
public void show() {
[Link]("show derived class");
}
}
public class Main {
public static void main(String[] args) {
Base bptr;
Derived d = new Derived();
bptr = d;
// virtual function, binded at runtime
[Link]();
// virtual function, binded at runtime
[Link]();
}
}
/*
output :
print derived class
show derived class
*/
Pure Virtual Function (Abstract Method):
1. A pure virtual function is not used for performing any task. It only serves as a placeholder.
2. A pure virtual function is a function declared in the base class that has no definition relative to the
base class.
3. A class containing the pure virtual function cannot be used to declare the objects of its own, such
classes are known as abstract base classes.
4. The main objective of the base class is to provide the traits to the derived classes and to create the
base reference used for achieving the runtime polymorphism.
Java Syntax:
abstract void display();
Java Example:
abstract class Base {
public abstract void show();
}
class Derived extends Base {
public void show() {
[Link]("You can see me !");
}
}
public class Main {
public static void main(String[] args) {
Base bptr;
Derived d = new Derived();
bptr = d;
[Link]();
}
}
// output : You can see me !
Abstract Classes: In Java class is made abstract by declaring at least one of its functions as an abstract
method. An abstract method is specified by using the abstract keyword in its declaration. Its implementation
must be provided by derived classes.
Example:
// abstract class
abstract class Shape {
public abstract void draw();
}
class Rectangle extends Shape {
public void draw() {
[Link]("Rectangle");
}
}
class Square extends Shape {
public void draw() {
[Link]("Square");
}
}
public class Main {
public static void main(String[] args) {
Rectangle rec = new Rectangle();
Square sq = new Square();
[Link]();
[Link]();
}
}
/*
Output :
Rectangle
Square
*/
Packages in Java:
1. The package is a logical division of the code which is designed to stop the naming conflict.
2. The package defines the scope where the identifiers such as variables, class, functions are declared.
3. The main purpose of using package in Java is to remove the ambiguity. Ambiguity occurs when a
different task occurs with the same name.
4. For example: if there are two functions with the same name such as add(). In order to prevent this
ambiguity, the package is used. Functions are declared in different packages.
5. Java consists of built-in packages such as [Link], [Link] which contain inbuilt classes and
functions. So, by using the statement "import [Link].*;" includes the package "[Link]" in our
program.
Java Example:
package [Link];
class Add {
static int a = 5, b = 5;
static int add() {
return (a + b);
}
}
// In another file or main class
import [Link];
public class Main {
public static void main(String[] args) {
int res = [Link](); // accessing the function inside package
[Link](res);
}
}
// output : 10
Access Specifiers (IMPORTANT): The access specifiers are used to define how functions and variables
can be accessed outside the class. There are three types of access specifiers:
1. Private: Functions and variables declared as private can be accessed only within the same class, and
they cannot be accessed outside the class they are declared.
2. Public: Functions and variables declared under public can be accessed from anywhere.
3. Protected: Functions and variables declared as protected cannot be accessed outside the class except
a child class. This specifier is generally used in inheritance.
Key Notes
In Java, garbage collection automatically manages memory, so there is no delete operator like in C++.
Java does not support multiple inheritance through classes to avoid ambiguity, but it can be achieved
through interfaces.
Function overloading: Function overloading is defined as we can have more than one version of the same
function. The versions of a function will have different signatures meaning that they have a different set of
parameters.
Operator overloading: Java does not support operator overloading except for the + operator (used for
String concatenation and addition).
Overloading is static Binding, whereas Overriding is dynamic Binding. Overloading is nothing but the same
method with different arguments, and it may or may not return the same value in the same class itself.
Overriding is the same method name with the same arguments and return types associated with the class and
its child class.