OOPs Features and Programming Models
OOPs Features and Programming Models
There are many reasons why OOPs is mostly preferred, but the most important among them are:
OOPs helps users to understand the software easily, although they don’t know the actual
implementation.
With OOPs, the readability, understandability, and maintainability of the code increase multifold.
Even very big software can be easily written and managed easily using OOPs.
The programming languages that use and follow the Object-Oriented Programming paradigm or
OOPs, are known as Object-Oriented Programming languages. Some of the major Object-Oriented
Programming languages include:
Java
C++
Javascript
Python
PHP
Nearly all programming paradigms include Structured programming, including the OOPs model.
OOPs or Object Oriented Programming mainly comprises of the below four features, and make sure
you don't miss any of these:
Inheritance
Encapsulation
Polymorphism
Data Abstraction
OOPs refers to Object-Oriented Programming. It is the programming paradigm that is defined using
objects. Objects can be considered as real-world instances of entities like class, that have some
characteristics and behaviors.
Access specifiers, as the name suggests, are a special type of keywords, which are used to control or specify
the accessibility of entities like classes, methods, etc. Some of the access specifiers or access modifiers
include “private”, “public”, etc. These access specifiers also play a very vital role in achieving Encapsulation
- one of the major features of OOPs.
Yes, with more powers comes more complications. Inheritance is a very powerful feature in OOPs, but it has
some limitations too. Inheritance needs more time to process, as it needs to navigate through multiple classes
for its implementation. Also, the classes involved in Inheritance - the base class and the child class, are very
tightly coupled together. So if one needs to make some changes, they might need to do nested changes in both
classes. Inheritance might be complex for implementation, as well. So if not correctly implemented, this
might lead to unexpected errors or incorrect outputs.
Single inheritance
Multiple inheritances
Multi-level inheritance
Hierarchical inheritance
Hybrid inheritance
4. What is a subclass?
The subclass is a part of Inheritance. The subclass is an entity, which inherits from another class. It is also
known as the child class.
5. Define a superclass?
Superclass is also a part of Inheritance. The superclass is an entity, which allows subclasses or child classes to
inherit from itself.
6. What is an interface?
An interface refers to a special type of class, which contains methods, but not their definition. Only the
declaration of methods is allowed inside an interface. To use an interface, you cannot create objects. Instead,
you need to implement that interface and define the methods for their implementation.
Static Polymorphism is commonly known as the Compile time polymorphism. Static polymorphism is the
feature by which an object is linked with the respective function or operator based on the values during the
compile time. Static or Compile time Polymorphism can be achieved through Method overloading or operator
overloading.
Dynamic Polymorphism or Runtime polymorphism refers to the type of Polymorphism in OOPs, by which
the actual implementation of the function is decided during the runtime or execution. The dynamic or runtime
polymorphism can be achieved with the help of method overriding.
Overloading is a compile-time polymorphism feature in which an entity has multiple implementations with
the same name. For example, Method overloading and Operator overloading.
Whereas Overriding is a runtime polymorphism feature in which an entity has the same name, but its
implementation changes during execution. For example, Method overriding.
Image
Data abstraction is accomplished with the help of abstract methods or abstract classes.
Interface and abstract classes both are special types of classes that contain only the methods declaration and
not their implementation. But the interface is entirely different from an abstract class. The main difference
between the two is that when an interface is implemented, the subclass must define all its methods and
provide its implementation. Whereas in object-oriented programming, when a subclass inherits from an
abstract class with abstract methods, the subclass is generally required to provide concrete implementations
for all of those abstract methods in the abstract class unless the subclass itself is declared as abstract.
Also, an abstract class can contain abstract methods as well as non-abstract methods.
Inheritance is one of the major features of object-oriented programming, by which an entity inherits some
characteristics and behaviors of some other entity and makes them their own. Inheritance helps to improve
and facilitate code reuse.
Let me explain to you with a common example. Let's take three different vehicles - a car, truck, or bus. These
three are entirely different from one another with their own specific characteristics and behavior. But. in all
three, you will find some common elements, like steering wheel, accelerator, clutch, brakes, etc. Though
these elements are used in different vehicles, still they have their own features which are common among all
vehicles. This is achieved with inheritance. The car, the truck, and the bus have all inherited the features like
steering wheel, accelerator, clutch, brakes, etc, and used them as their own. Due to this, they did not have to
create these components from scratch, thereby facilitating code reuse.
An exception can be considered as a special event, which is raised during the execution of a program at
runtime, that brings the execution to a halt. The reason for the exception is mainly due to a position in the
program, where the user wants to do something for which the program is not specified, like undesirable input.
Object-oriented programming revolves around entities like objects. Each object consumes memory and there
can be multiple objects of a class. So if these objects and their memories are not handled properly, then it
might lead to certain memory-related errors and the system might fail.
Garbage collection refers to this mechanism of handling the memory in the program. Through garbage
collection, the unwanted memory is freed up by removing the objects that are no longer needed.
17. Can we run a Java application without implementing the OOPs concept?
No. Java applications are based on Object-oriented programming models or OOPs concept, and hence they
cannot be implemented without it.
However, on the other hand, C++ can be implemented without OOPs, as it also supports the C-like structural
programming model.
18. What is Compile time Polymorphism and how is it different from Runtime
Polymorphism?
Compile Time Polymorphism: Compile time polymorphism, also known as Static Polymorphism, refers to the
type of Polymorphism that happens at compile time. What it means is that the compiler decides what shape or
value has to be taken by the entity in the picture.
Example:
// In this program, we will see how multiple functions are created with the same name,
// but the compiler decides which function to call easily at the compile time itself.
class CompileTimePolymorphism{
// 1st method with name add
public int add(int x, int y){
return x+y;
}
// 2nd method with name add
public int add(int x, int y, int z){
return x+y+z;
}
// 3rd method with name add
public int add(double x, int y){
return (int)x+y;
}
// 4th method with name add
public int add(int x, double y){
return x+(int)y;
}
}
class Test{
public static void main(String[] args){
CompileTimePolymorphism demo=new CompileTimePolymorphism();
// In the below statement, the Compiler looks at the argument types and decides to
call method 1
System.out.println(demo.add(2,3));
// Similarly, in the below statement, the compiler calls method 2
System.out.println(demo.add(2,3,4));
// Similarly, in the below statement, the compiler calls method 4
System.out.println(demo.add(2,3.4));
// Similarly, in the below statement, the compiler calls method 3
System.out.println(demo.add(2.5,3));
}
}
In the above example, there are four versions of add methods. The first method takes two parameters while
the second one takes three. For the third and fourth methods, there is a change of order of parameters. The
compiler looks at the method signature and decides which method to invoke for a particular method call at
compile time.
Runtime Polymorphism: Runtime polymorphism, also known as Dynamic Polymorphism, refers to the type
of Polymorphism that happens at the run time. What it means is it can't be decided by the compiler. Therefore
what shape or value has to be taken depends upon the execution. Hence the name Runtime Polymorphism.
Example:
class AnyVehicle{
public void move(){
System.out.println(“Any vehicle should move!!”);
}
}
class Bike extends AnyVehicle{
public void move(){
System.out.println(“Bike can move too!!”);
}
}
class Test{
public static void main(String[] args){
AnyVehicle vehicle = new Bike();
// In the above statement, as you can see, the object vehicle is of type AnyVehicle
// But the output of the below statement will be “Bike can move too!!”,
// because the actual implementation of object ‘vehicle’ is decided during runtime
vehicle.move();
vehicle = new AnyVehicle();
// Now, the output of the below statement will be “Any vehicle should move!!”,
vehicle.move();
}
}
As the method to call is determined at runtime, as shown in the above code, this is called runtime
polymorphism.
A class can be understood as a template or a blueprint, which contains some values, known as member data or
member, and some set of rules, known as behaviors or functions. So when an object is created, it
automatically takes the data and functions that are defined in the class.
Therefore the class is basically a template or blueprint for objects. Also one can create as many objects as
they want based on a class.
For example, first, a car’s template is created. Then multiple units of car are created based on that template.
An object refers to the instance of the class, which contains the instance of the members and behaviors
defined in the class template. In the real world, an object is an actual entity to which a user interacts, whereas
class is just the blueprint for that object. So the objects consume space and have some characteristic behavior.
For example, a specific car.
One can visualize Encapsulation as the method of putting everything that is required to do the job, inside a
capsule and presenting that capsule to the user. What it means is that by Encapsulation, all the necessary data
and methods are bind together and all the unnecessary details are hidden to the normal user. So Encapsulation
is the process of binding data members and methods of a program together to do a specific job, without
revealing unnecessary details.
1) Data hiding: Encapsulation is the process of hiding unwanted information, such as restricting access to
any member of an object.
2) Data binding: Encapsulation is the process of binding the data members and the methods together as a
whole, as a class.
Polymorphism is composed of two words - “poly” which means “many”, and “morph” which means
“shapes”. Therefore Polymorphism refers to something that has many shapes.
In OOPs, Polymorphism refers to the process by which some code, data, method, or object behaves
differently under different circumstances or contexts. Compile-time polymorphism and Run time
polymorphism are the two types of polymorphisms in OOPs languages.
Compile Time Polymorphism: C++ supports compile-time polymorphism with the help of features like
templates, function overloading, and default arguments.
Runtime Polymorphism: C++ supports Runtime polymorphism with the help of features like virtual functions.
Virtual functions take the shape of the functions based on the type of object in reference and are resolved at
runtime.
The term “inheritance” means “receiving some quality or behavior from a parent to an offspring.” In object -
oriented programming, inheritance is the mechanism by which an object or class (referred to as a child) is
created using the definition of another object or class (referred to as a parent). Inheritance not only helps to
keep the implementation simpler but also helps to facilitate code reuse.
If you are a user, and you have a problem statement, you don't want to know how the components of the
software work, or how it's made. You only want to know how the software solves your problem. Abstraction
is the method of hiding unnecessary details from the necessary ones. It is one of the main features of OOPs.
For example, consider a car. You only need to know how to run a car, and not how the wires are connected
inside it. This is obtained using Abstraction.
Classes do not consume any memory. They are just a blueprint based on which objects are created. Now
when objects are created, they actually initialize the class members and methods and therefore consume
memory.
No. An object is necessary to be created if the base class has non-static methods. But if the class has static
methods, then objects don’t need to be created. You can call the class method directly in this case , using the
class name.
Constructors are special methods whose name is the same as the class name. The constructors serve the
special purpose of initializing the objects.
For example, suppose there is a class with the name “MyClass”, then when you instantiate this class, you pass
the syntax:
MyClass myClassObject = new MyClass();
Now here, the method called after “new” keyword - MyClass(), is the constructor of this class. This will help
to instantiate the member data and methods and assign them to the object myClassObject.
class ABC
{
int x;
ABC()
{
x = 0;
}
}
Parameterized constructor: The constructors that take some arguments are known as parameterized
constructors.
class ABC
{
int x;
ABC(int y)
{
x = y;
}
}
Copy constructor: A copy constructor is a member function that initializes an object using another object of
the same class.
class ABC
{
int x;
ABC(int y)
{
x = y;
}
// Copy constructor
ABC(ABC abc)
{
x = abc.x;
}
}
Copy Constructor is a type of constructor, whose purpose is to copy an object to another. What it means is
that a copy constructor will clone an object and its values, into another object, is provided that both the
objects are of the same class.
Contrary to constructors, which initialize objects and specify space for them, Destructors are also special
methods. But destructors free up the resources and memory occupied by an object. Destructors are
automatically called when an object is being destroyed.
32. Are class and structure the same? If not, what's the difference between a class and a
structure?
No, class and structure are not the same. Though they appear to be similar, they have differences that make
them apart. For example, the structure is saved in the stack memory, whereas the class is saved in the heap
memory. Also, Data Abstraction cannot be achieved with the help of structure, but with class, Abstraction is
majorly used.
class BaseClass2 {
public:
BaseClass2()
{ cout << "BaseClass2 constructor called" << endl; }
};
int main()
{
DerivedClass derived_class;
return 0;
}
Output:
Reason:
The above program demonstrates Multiple inheritances. So when the Derived class’s constructor is called, it
automatically calls the Base class's constructors from left to right order of inheritance.
static
{
System.out.println(“a”);
i = 100;
}
}
System.out.println(Scaler.i);
}
}
Output:
b
c
a
100
Reason:
Firstly the static block inside the main-method calling class will be implemented. Hence ‘b’ will be printed
first. Then the main method is called, and now the sequence is kept as expected.
class ClassA {
public:
ClassA(int ii = 0) : i(ii) {}
void show() { cout << "i = " << i << endl;}
private:
int i;
};
class ClassB {
public:
ClassB(int xx) : x(xx) {}
operator ClassA() const { return ClassA(x); }
private:
int x;
};
void g(ClassA a)
{ a.show(); }
int main() {
ClassB b(10);
g(b);
g(20);
getchar();
return 0;
}
Output:
i = 10
i = 20
Reason:
ClassA contains a conversion constructor. Due to this, the objects of ClassA can have integer values. So the
statement g(20) works. Also, ClassB has a conversion operator overloaded. So the statement g(b) also works.
Output:
Main1
Reason:
Here the main() method is overloaded. But JVM only understands the main method which has a String[]
argument in its definition. Hence Main1 is printed and the overloaded main method is ignored.
class BaseClass{
int arr[10];
};
int main(void)
{
cout<<sizeof(DerivedClass);
return 0;
}
Output:
If the size of the integer is 4 bytes, then the output will be 80.
Reason:
Since DerivedBaseClass1 and DerivedBaseClass2 both inherit from class BaseClass, DerivedClass contains
two copies of BaseClass. Hence it results in wastage of space and a large size output. It can be reduced with
the help of a virtual base class.
class B : public A {
public:
void print()
{ cout <<" Inside B"; }
};
class C: public B {
};
int main(void)
{
C c;
c.print();
return 0;
}
Output:
Inside B
Reason:
The above program implements a Multi-level hierarchy. So the program is linearly searched up until a
matching function is found. Here, it is present in both classes A and B. So class B’s print() method is called
1. What is Object Oriented Programming (OOPs)?
Object Oriented Programming (also known as OOPs) is a programming paradigm where the
complete software operates as a bunch of objects talking to each other. An object is a collection of
data and the methods which operate on that data.
2. Why OOPs?
The main advantage of OOP is better manageable code that covers the following:
1. The overall understanding of the software is increased as the distance between the language
spoken by developers and that spoken by users.
2. Object orientation eases maintenance by the use of encapsulation. One can easily change the
underlying representation by keeping the methods the same.
3. The OOPs paradigm is mainly useful for relatively big software.
3. What is a Class?
A class is a building block of Object Oriented Programs. It is a user-defined data type that contains
the data members and member functions that operate on the data members. It is like a blueprint or
template of objects having common properties and methods.
4. What is an Object?
An object is an instance of a class. Data members and methods of a class cannot be used directly.
We need to create an object (or instance) of the class to use them. In simple terms, they are the actual
world entities that have a state and behavior.
C++JavaPythonC#
#include <iostream>
using namespace std;
// defining class
class Student {
public:
string name;
};
int main()
{
// creating object
Student student1;
// assigning member some value
student1.name = "Rahul";
return 0;
}
Output
student1.name: Rahul
5. What are the main features of OOPs?
The main feature of the OOPs, also known as 4 pillars or basic principles of OOPs are as follows:
1. Encapsulation
2. Data Abstraction
3. Polymorphism
4. Inheritance
OOPs Main Features
6. What is Encapsulation?
Encapsulation is the binding of data and methods that manipulate them into a single unit such that
the sensitive data is hidden from the users
It is implemented as the processes mentioned below:
1. Data hiding: A language feature to restrict access to members of an object. For example,
private and protected members in C++.
2. Bundling of data and methods together: Data and methods that operate on that data are
bundled together. For example, the data members and member methods that operate on them are
wrapped into a single unit known as a class.
7. What is Abstraction?
Abstraction is similar to data encapsulation and is very important in OOP. It means showing only the
necessary information and hiding the other irrelevant information from the user. Abstraction is
implemented using classes and interfaces.
8. What is Polymorphism?
The word “Polymorphism” means having many forms. It is the property of some code to behave
differently for different contexts. For example, in C++ language, we can define multiple functions
having the same name but different working depending on the context.
Polymorphism can be classified into two types based on the time when the call to the object or
function is resolved. They are as follows:
Compile Time Polymorphism
Runtime Polymorphism
A) Compile-Time Polymorphism
Compile time polymorphism, also known as static polymorphism or early binding is the type of
polymorphism where the binding of the call to its code is done at the compile time. Method
overloading or operator overloading are examples of compile-time polymorphism.
B) Runtime Polymorphism
Also known as dynamic polymorphism or late binding, runtime polymorphism is the type of
polymorphism where the actual implementation of the function is determined during the runtime or
execution. Method overriding is an example of this method.
9. What is Inheritance? What is its purpose?
The idea of inheritance is simple, a class is derived from another class and uses data and
implementation of that other class. The class which is derived is called child or derived or subclass
and the class from which the child class is derived is called parent or base or superclass.
The main purpose of Inheritance is to increase code reusability. It is also used to achieve Runtime
Polymorphism.
10. What are access specifiers? What is their significance in OOPs?
Access specifiers are special types of keywords that are used to specify or control the accessibility of
entities like classes, methods, and so on. Private, Public, and Protected are examples of access
specifiers or access modifiers.
The key components of OOPs, encapsulation and data hiding, are largely achieved because of these
access specifiers.
11. What are the advantages and disadvantages of OOPs?
Advantages of OOPs Disadvantages of OOPs
The code is easier to maintain and Proper planning is required because OOPs is a little bit
update. tricky.
Restricts the open flow of data to authorized No restriction to the flow of data. Anyone can access
parts only providing better data security. the data.
Enhanced code reusability due to the Code reusability is achieved by using functions and
concepts of polymorphism and inheritance. loops.
Modifying and updating the code is easier. Modifying the code is difficult as compared to OOPs.
14. What are some commonly used Object Oriented Programming Languages?
OOPs paradigm is one of the most popular programming paradigms. It is widely used in many
popular programming languages such as:
C++
Java
Python
JavaScript
C#
Ruby
15. What are the different types of Polymorphism?
Polymorphism can be classified into two types based on the time when the call to the object or
function is resolved. They are as follows:
1. Compile Time Polymorphism
2. Runtime Polymorphism
Types of Polymorphism
A) Compile-Time Polymorphism
Compile time polymorphism, also known as static polymorphism or early binding is the type of
polymorphism where the binding of the call to its code is done at the compile time. Method
overloading or operator overloading are examples of compile-time polymorphism.
B) Runtime Polymorphism
Also known as dynamic polymorphism or late binding, runtime polymorphism is the type of
polymorphism where the actual implementation of the function is determined during the runtime or
execution. Method overriding is an example of this method.
16. What is the difference between overloading and overriding?
A compile-time polymorphism feature called overloading allows an entity to have numerous
implementations of the same name. Method overloading and operator overloading are two
examples.
Overriding is a form of runtime polymorphism where an entity with the same name but a different
implementation is executed. It is implemented with the help of virtual functions.
17. Are there any limitations on Inheritance?
Yes, there are more challenges when you have more authority. Although inheritance is a very
strong OOPs feature, it also has significant drawbacks.
As it must pass through several classes to be implemented, inheritance takes longer to process.
The base class and the child class, which are both engaged in inheritance, are also closely
related to one another (called tightly coupled). Therefore, if changes need to be made, they may
need to be made in both classes at the same time.
Implementing inheritance might be difficult as well. Therefore, if not implemented correctly,
this could result in unforeseen mistakes or inaccurate outputs.
18. What different types of Inheritance are there?
Inheritance can be classified into 5 types which are as follows:
1. Single Inheritance: Child class derived directly from the base class
2. Multiple Inheritance: Child class derived from multiple base classes.
3. Multilevel Inheritance: Child class derived from the class which is also derived from another
base class.
4. Hierarchical Inheritance: Multiple child classes derived from a single base class.
5. Hybrid Inheritance: Inheritance consisting of multiple inheritance types of the above
specified.
Note: Type of inheritance supported is dependent on the language. For example, Java does not
support multiple inheritance.
19. What is an interface?
A unique class type known as an interface contains methods but not their definitions. Inside an
interface, only method declaration is permitted. You cannot make objects using an interface. Instead,
you must put that interface into use and specify the procedures for doing so.
20. How is an abstract class different from an interface?
Both abstract classes and interfaces are special types of classes that just include the declaration of the
methods, not their implementation. An abstract class is completely distinct from an interface, though.
Following are some major differences between an abstract class and an interface.
Abstract Class Interface
A class that is abstract can have both abstract and non- An interface can only have abstract
abstract methods. methods.
An abstract class can have final, non-final, static and non- The interface has only static and final
static variables. variables.
C++JavaPython
class base {
public:
int base;
base(int var)
{
cout << "Constructor with argument: " << var;
}
};
4. Copy Constructor
A copy constructor is a member function that initializes an object using another object of the same
class.
Example:
C++Java
class base {
int a, b;
base(base& obj) // copy constructor
{
a = obj.a;
b = obj.b;
}
}
In Python, we do not have built-in copy constructors like Java and C++ but we can make a
workaround using different methods.
26. What is a destructor?
A destructor is a method that is automatically called when the object is made of scope or destroyed.
In C++, the destructor name is also the same as the class name but with the (~) tilde symbol as the
prefix.
In Python, the destructor is named __del__.
Example:
C++Python
class base {
public:
~base() { cout << "This is a destructor"; }
}
In Java, the garbage collector automatically deletes the useless objects so there is no concept of
destructor in Java. We could have used finalize() method as a workaround for the java destructor but
it is also deprecated since Java 9.
27. Can we overload the constructor in a class?
Yes We can overload the constructor in a class in Java. Constructor Overloading is done when we
want constructor with different constructor with different parameter(Number and Type).
28. Can we overload the destructor in a class?
No, a destructor cannot be overloaded in a class. There can only be one destructor present in a
class.
29. What is the virtual function?
A virtual function is a function that is used to override a method of the parent class in the derived
class. It is used to provide abstraction in a class.
In C++, a virtual function is declared using the virtual keyword,
In Java, every public, non-static, and non-final method is a virtual function.
Python methods are always virtual.
Example:
C++JavaPython
class base {
virtual void print()
{
cout << "This is a virtual function";
}
}
30. What is pure virtual function?
A pure virtual function, also known as an abstract function is a member function that doesn’t
contain any statements. This function is defined in the derived class if needed.
1. What Are OOPs?
This is one of the most commonly asked OOPs interview questions. Object-Oriented
Programming is a programming paradigm that uses objects instead of functions and procedures.
These objects are grouped into classes. OOP incorporates real-world entities like inheritance,
polymorphism, and encapsulation into programming, allowing for the integration of data and
methods.
OOP organizes code into objects, making complex problems easier to understand and solve.
Properties and methods from parent classes are inherited by child classes, promoting efficient
code reuse.
By using inheritance and creating reusable objects, OOP minimizes code duplication.
OOP bundles data and the functions that manipulate it within a single unit or object.
Access modifiers in OOP control the visibility of internal object details, enhancing security and
reducing system complexity.
OOP allows breaking down complex problems into smaller, manageable subproblems
represented by objects.
Java
C++
C#
Python
Ruby
JavaScript
Swift
PHP
Objective-C
Classes: Classes in OOP are essential components, acting as templates for objects. They
define the data structure and behavior of objects, encapsulating attributes and methods to
provide a modular and organized design framework.
Objects: In OOP, objects are core elements that represent real-world entities with distinct
attributes and behaviors. As instances of classes, they encapsulate data and methods,
enhancing code modularity and organization. Objects communicate via well-defined interfaces,
supporting structured design principles.
Inheritance: Inheritance enables a class to inherit fields and methods from another class,
fostering code reuse and creating a hierarchical class structure.
Encapsulation: Encapsulation combines data and methods that operate on that data into a
single unit called a class. It also restricts direct access to some of an object’s components.
Polymorphism: Polymorphism, a key feature of OOP, allows objects from different classes to
be treated as objects of a common base class.
5. What Is an Object?
An object in Object-Oriented Programming is a fundamental unit representing real-world entities.
It is an instance of a class, with memory allocated only upon instantiation (object creation).
Objects possess identity, state, and behavior, containing data and code to manipulate it.
Interaction between objects doesn't require knowledge of each other's data or code specifics,
just the types of messages accepted and responses provided.
6. What Is a Class?
A class is a user-defined data type that consists of data members and member functions
accessible through an instance of the class. It represents the common properties or methods of
all objects of a specific type, functioning as a blueprint for an object.
Used for complex data types and to Used for simple, lightweight data types
Recommended Usage
model real-world entities. and grouping-related data.
Memory A class itself does not occupy any Objects occupy memory space when they
Allocation memory space. are created.
Classes can inherit properties and Objects cannot inherit directly from other
Inheritance methods from other classes through objects but from the class they are
inheritance. instantiated from.
Code Reusability: Utilizes class-based architecture for modular design, enabling instantiation
of objects from reusable class templates. This promotes code efficiency through multiple
instantiations.
Enhanced Security: Implements encapsulation for data protection, utilizes access modifiers
to control the visibility of class members and employs abstraction to expose only necessary
interfaces.
Efficient Debugging: Utilizes self-contained objects for localized error isolation, implements
exception handling for robust error management, and reduces code duplication, minimizing
potential error sources.
Imperative Programming Paradigm: This approach specifies how to execute program logic
and defines a sequence of commands to change program state. It includes:
Procedural Programming Paradigm: This method defines a set of computational
steps to be carried out and executed in order from top to bottom.
Parallel Programming: This focuses on breaking down tasks into smaller components
that can be processed concurrently.
Declarative Programming Paradigm: This approach emphasizes what the program should
accomplish without explicitly specifying control flow. It includes:
Logical Programming Paradigm: Based on formal logic, this uses a set of statements
expressing facts and rules to solve problems.
Database Programming Paradigm: This model manages data organized into fields,
records, and files.
Complexity Simpler for small programs Better for managing complex programs
Public
Private
Protected
Public: Use when you want class members to be accessible from anywhere in the program.
They are typically used for methods that need to be called by external code or for data that
should be freely accessible.
Private: Use when you want to restrict access to class members only within the same class.
Helps in hiding implementation details and maintaining data integrity. Useful for internal helper
methods or variables that should not be directly manipulated from outside the class.
Protected: Use when you want to allow access to class members within the same class and
its subclasses. Useful when implementing inheritance and you want to share some internal
functionality with derived classes.
It bundles related data and functions together into a single unit (like a class).
It hides the complex internal functioning and shows only what's necessary to use it.
Data Abstraction: Data abstraction is the most simple implementation of abstraction. When
dealing with many complex processes, we hide unnecessary data and display only the
information necessary for the users.
Process Abstraction: When we hide the internal implementation and do not disclose all the
details about a method or function to the users, this is known as process abstraction. Instead
of dealing with data, we deal with their process in this type of abstraction.
For example, you could have a method that processes "Shape" objects, and it would work
correctly whether you pass it a "Circle," "Square," or "Triangle" object, as long as they're all
subclasses of "Shape."
Occurs when multiple methods in the same class have the same name but different
parameters.
The compiler specifies which method to call based on the method signature.
Occurs when a subclass gives a specific implementation for a method already defined
in its superclass.
The JVM determines which method to call based on the object's actual type at runtime.
Same Method Name: All overloaded methods share the same name within a class.
Different Parameters: The methods must differ in the number, type, or order of parameters.
Return Type: The return type can be different, but this alone is not enough to overload a
method.
class Calculator {
public int add(int a, int b) {
return a + b;
}
Same Method Signature: The method in the subclass that overrides a method from the
superclass must have the same name, return type, and parameter list as the method in the
superclass.
Runtime Polymorphism: The decision about which method to call is made at runtime, not at
compile time.
Access Modifiers: The overriding method must not have a stricter access level than the
overridden method.
class Shape {
double getArea() {
return 0;
}
}
Circle(double radius) {
this.radius = radius;
}
@Override
double getArea() {
return Math.PI * radius * radius;
}
}
@Override
double getArea() {
return width * height;
}
}
Method Must have different parameter types or Must have the same method signature (name
Signature a number of parameters. and parameters).
Static/Non-
Can be either Must be non-static
static
Also Known As Static binding, early binding Dynamic binding, late binding
Runtime polymorphism is achieved through method overriding, not data members (variables).
This is because data members are not overridden, so runtime polymorphism doesn't apply to them.
What occurs with data members is actually called "hiding" rather than overriding.
Syntax:
class SubClass extends SuperClass {
// SubClass members
}
Single inheritance
Multiple inheritance
Multilevel inheritance
Hierarchical inheritance
Hybrid inheritance
Performance Overhead: Inherited methods typically execute more slowly than regular functions due to
the additional layer of indirection.
Potential for Misuse: Incorrect application of inheritance can result in flawed or inappropriate solutions
to programming problems.
Inefficient Resource Utilization: Base classes may contain data members that remain unused in
derived classes, potentially leading to unnecessary memory consumption.
Increased Interdependence: Inheritance creates a tighter coupling between parent and child classes.
Modifications to the base class can have far-reaching effects on all its descendants.
With inheritance, we'd save time writing the same code repeatedly for similar classes. It's like
reinventing the wheel each time instead of just using a wheel that already exists.
The ability for the contained entity to be associated with multiple containers.
Example in Java:
Composition: Composition denotes a strong, whole-part relationship between two entities where
the part cannot exist without the whole.
The part is an integral component of the whole and cannot exist independently.
The whole is responsible for the creation and destruction of its parts.
Implementation often involves creating part objects within the whole's constructor.
Example in Java:
Entity Independence: Aggregated entities can exist independently; composed entities cannot.
Lifespan Management: Aggregating objects don't control the lifespan of aggregated entities;
composing objects do control the lifespan of their parts.
Coupling: Aggregation results in loose coupling, while composition creates tighter coupling
between entities.
34. What Is the Difference Between Inheritance
and Polymorphism?
Following are the differences between inheritance and polymorphism:
Code reuse and establishing a hierarchical Flexibility in using different object types
Purpose
relationship between classes. through a common interface.
Achieved using the extends keyword (in Achieved through method overriding and
Implementation
many languages). interfaces/abstract classes.
Creates tight coupling between parent and Promotes loose coupling through
Coupling
child classes. abstraction.
No-Arg constructor
Parameterized constructor
Default constructor
Initialize an object to a default state when no arguments are provided during object creation.
Ensure that an object can be created without explicitly specifying initial values.
Constructors share the same name as their class and can be overloaded to accept different
parameters. While they resemble methods in some ways, constructors are distinct in that th ey
can't be directly called and aren't part of the object's interface.
Many languages provide a default no-argument constructor if none is explicitly defined, and
constructors can often chain to other constructors or superclass constructors to build comple x
initialization sequences.
Same Name: All constructors have the same name as the class.
Automatic Selection: The appropriate constructor is called based on the arguments provided
during object creation.
The appropriate constructor is automatically called based on the arguments provided when
creating new Rectangle objects.
Within the Same Class: Use this for chaining constructors within the same class.
From the Base Class: Use superfor chaining constructors from different classes (parent and
child).
Invocation:
person.setName("peter");
Naming:
Constructor: The name of a constructor must be the same as the name of the class in
which it is defined.
Method: A method can have any name, except it cannot be the same as the class
name if it has a return type.
Return Type:
Constructor: Constructors do not have a return type, not even void. The object being
constructed is implicitly returned.
Method: Methods must have a return type, which can be a primitive type, an object
type, or void if no value is returned.
Inheritance:
Constructor: Constructors are not inherited by subclasses. Each class must define its
own constructors.
Object Initialization:
Constructor: A constructor initializes an object that does not yet exist. It sets up the
initial state of the object.
Note : Test your web and mobile apps across 3000+ real desktop browsers. Leading digital
experience testing for insurance sector.
Interface
Abstract classes contain one or more abstract methods or behaviors. Abstracting o bjects or
classes means summarizing their characteristics relevant to the current program's operation.
Abstract classes are utilized in all Object-Oriented Programming languages, including Java, C++,
C#, and VB.NET.
Unlike classes in many OOP languages, a single class can implement multiple interfaces,
allowing for a form of multiple inheritance.
Interfaces enable loose coupling between different parts of a system, as classes can depend
on interfaces rather than concrete implementations.
Objects of different classes implementing the same interface can be treated uniformly,
enhancing code flexibility.
Interfaces act as contracts between different system components, clearly defining expected
behavior.
4. How Is an Abstract Class Different From an
Interface?
This is one of the frequently encountered OOPs interview questions. The reason is that abstract
classes can contain non-final variables, while variables in an interface are final, public, and
static.
interface SimpleInterface {
int CONSTANT = 100; // implicitly public, static, and final
}
The above example shows that interfaces can only have constants, while abstract classes can
have mutable instance variables.
The following table demonstrates the difference between an abstract class and interface.
Static methods belong to the class itself, not to any specific instance.
The purpose of an interface is to define a contract that implementing classes must follow,
which involves instance methods.
In Java 8 and later, you can have static methods in interfaces, but these are not considered
part of the interface contract. They are utility methods associated with the interface.
In C# 8.0 and later, interfaces can have static members, including static methods, but these
are not inherited by implementing classes.
Constructors are specifically designed to initialize new object instances when they are created.
They set up the initial state of an object and are called automatically when an object is
instantiated using the new keyword.
Static members, on the other hand, belong to the class itself rather than to any specific instance
of the class. They can be accessed without creating an object of the class.
Making a constructor static would contradict its fundamental purpose of initializing individual
object instances. It would also conflict with object creation and initialization in Object-Oriented
Programming.
If you need class-level initialization, most languages provide other mechanisms like static
initializer blocks or static methods that can be used for this purpose.
The name of the constructor must be the same as the class name.
Multiple constructors can exist in the same class, known as constructor overloading.
A default constructor is provided by Java and invoked during object creation unless you define
any constructor.
Declaring it as private would prevent it from being accessed and implemented outside the class.
10. What Is the Virtual Function?
In Object-Oriented Programming, such as C++, a virtual function or method is an inheritable and
overridable function dispatched dynamically. Virtual functions play a crucial role in runtime
polymorphism in OOP, enabling the execution of target functions that are not precisely identified
at compile time.
Many programming languages, including JavaScript, PHP, and Python, treat all methods as
virtual by default and do not offer a modifier to alter this behavior. However, specific languages
provide modifiers like final and private in Java and PHP to prevent methods from being
overridden by derived classes.
Incomplete Implementation: Abstract classes can contain both fully implemented methods
and abstract methods (methods without a body).
Cannot be Instantiated: You cannot create objects directly from an abstract class.
Meant for Inheritance: Abstract classes are designed to be subclassed by other classes that
provide implementations for the abstract methods.
Can Have Constructors: Although they can't be instantiated directly, abstract classes can
have constructors to initialize fields.
May Contain Instance Variables: Abstract classes can define and initialize instance
variables.
Can Have any Access Modifier: Methods in an abstract class can be public, protected, or
private.
Support for Multiple Inheritance: In languages like Java, abstract classes can extend
another class and implement interfaces.
Can Have Static Members: Abstract classes can contain static methods and variables.
May Contain Final Methods: These cannot be overridden by subclasses.
Provide a Common Interface: They often define a common structure for a group of related
subclasses.
Self-assignment
Not needed Often needed to handle a = a case.
check
Memory allocation Always allocates new memory. May or may not allocate new memory.
Usage with new Can be used with new. Cannot be used with new.
Default
Performs shallow copy. Performs shallow copy.
implementation
Encapsulation encapsulates the internal workings of an object, maintaining its state and
operations within a defined scope. Abstraction focuses on defining a clear and concise
interface for interaction.
Abstraction simplifies software design by focusing on essential features, promoting clarity, and
reducing complexity.Encapsulation ensures that data integrity and security are maintained by
controlling access to internal states and methods.
Encapsulation manages how data is stored and accessed internally, while Abstraction
simplifies interaction with complex systems by providing a clear, high-level view.
While encapsulation protects data by encapsulating it within a class and providing controlled
access methods, Abstraction simplifies the representation of systems by focusing on essential
behaviors and ignoring unnecessary details.
Overhead for the class itself (e.g., vtable pointer for classes with virtual functions).
The actual memory usage can be larger than the sum of the sizes of data members due to:
Virtual function table pointers (in C++ for classes with virtual functions).
Tight coupling
Loose coupling
Tight coupling makes testing difficult, while loose coupling makes it easier.
Tight coupling makes it hard to swap code between classes; loose coupling allows for easier
swapping of modules.
Tight coupling is inflexible to changes, whereas loose coupling supports easier modifications.
Function-Based Manipulators:
These are functions that take a stream reference as an argument and return the same
stream reference.
The stream's operator << or operator >> is overloaded to handle these functions.
When encountered in an I/O statement, the manipulator function modifies the stream.
Class-Based Manipulators:
Manipulators typically change internal flags or data members of the stream object.
Chaining:
Manipulators can be chained in a single statement because they return the stream
object.
Persistence:
Others (like the setw() function) affect only the next I/O operation.
They often use stream member functions to modify the stream's state.
Derived Classes:
In the application:
//cpp
vector<AudioFile*> playlist;
playlist.push_back(new MP3File("Song1.mp3"));
playlist.push_back(new WAVFile("Song2.wav"));
playlist.push_back(new AADFile("Song3.aad"));
Here, the play() method is called on each song in the playlist. The actual implementation called
depends on the specific file type, demonstrating polymorphism:
This example shows how polymorphism allows the application to treat different audio file types
uniformly through a common interface (AudioFile) while executing the appropriate play() method
for each specific file type.
Definition The class from which other classes inherit. The class from which other classes inherit.
Purpose Provides common attributes and methods. Provides common attributes and methods.
Inheritance Other classes derive from it. Other classes extend from it.
This level is typically hidden from the user and handled by the programming language
or runtime environment.
It includes the attributes (data members) and methods (member functions) that make up
a class.
This level is where the programmer defines the blueprint for objects.
It defines how users or other parts of the program interact with objects.
This level typically includes public methods and properties that are accessible to users
of the class.
It hides the internal implementation details and exposes only what's necessary for using
the object.
Local variables
Only public static void main(String[] args) serves as the program's entry point.
Other main methods are treated as regular methods and can be called from within the
program.
These additional main() methods don't affect how the program is started by the JVM.
This approach can help organize code or provide different ways to process input, but it's not
true method overloading from the JVM's perspective.
When you create a new object by assigning an existing object to it, Java perfo rms a shallow copy
by default. A shallow copy creates a new object and copies the reference values of the instance
variables from the original object to the new object. This means that both objects will share the
same reference to mutable objects (objects that can be modified after creation, such as arrays or
other custom objects).
To create a copy constructor, start by defining a constructor that accepts an object of the same
type as its parameter:
Afterward, each field of the input object is copied into the new instance:
What we have here is a shallow copy, which is suitable because all our fields —such
as String and int—are either primitive types or immutable types.
If the Java class contains mutable fields, an alternative approach in its copy constructor is to
perform a deep copy. This ensures that the newly created object is independent of the original
one by creating distinct copies of each mutable object:
Unlike clone, which returns a general object reference requiring typecasting, the copy
constructor directly returns the appropriate type.
Copy constructors can assign values to final fields, which is impossible with the clone method.
All objects of the class access the same copy of a static variable.
Static variables conserve memory as they are not duplicated for each instance.
Static variables are declared using the static keyword at the class level.
Static variables and static blocks are initialized in the order they appear in the code.
You can access static variables directly through the class name without creating an instance of
the class.
Syntax:
[Access_modifier] static [return_type] methodName([parameters]) {
// Method body
}
Non-Static Access:
This restriction exists because static methods operate at the class level, not on specific
instances.
The this keyword refers to the current instance, which doesn't exist in a static context.
super refers to the parent class instance, which doesn't apply in a static context.
Static methods can only directly access static data (static variables or other static
methods).
A static method would need an object reference passed as a parameter to access
instance data.
No True Overriding:
A subclass can define a method with the same signature, but this is method hiding, not
overriding.
Every Java program begins with the main() function. The main() method is essential because
the compiler begins executing a program from the main() function only.
The JVM should instantiate the class if the main() function is non-static.
JVM can simply invoke static methods without generating an instance of the class by utilizing
only the class name.
The main() function must be declared static, and public, and must have a void return type. The
JVM will be unable to run the Java program and will throw an error if we do not declare it as
static and public or if we do not provide it with a void return type.
Here's an example:
public class MyClass {
private static int counter;
private static final double PI;
static {
counter = 0;
PI = calculatePi(); // Assume calculatePi() is a method that computes the value
of pi
System.out.println("Static block executed");
}
In this example, the Static block initializes the counter variable to 0 and the PI constant with the
value computed by the calculatePi() method. The message Static block executed will be printed
when the MyClass is loaded into memory.
Even if compilation was somehow successful, the Java Virtual Machine could not execute the
program. The JVM looks explicitly for a static main() method as the entry point for any Java
application.
Without the static modifier, the main would become an instance method. This creates a
paradoxical situation where the JVM would need to create an object of the class to call
the main() method, but it can't create an object without already having a running program.
The Java language specification explicitly requires the main() method to be static. A non-
static main() method does not conform to these specifications, making the program invalid as
a Java application.
Instance methods have direct access to other instance methods and instance variables.
Instance methods also have direct access to static variables and static methods.
Static methods can directly access static variables and static methods.
Static methods cannot directly access instance methods and instance variables; they must use
an object reference. Furthermore, static methods cannot use this keyword since no instance
exists to reference.
When instance variables are shadowed by method or constructor parameters, this helps
distinguish them.
This example shows how constructor chaining is done using this keyword:
The three-parameter constructor initializes all fields and sets brand-specific details.
In this scenario, if B and C both override a method from A, which version should D inherit?
This ambiguity can lead to:
The super() call must be the first statement in the subclass constructor.
If not explicitly called, the compiler automatically inserts super() to call the no-argument
constructor of the superclass.
public Vehicle() {
this("Unknown", "Unknown");
}
public Vehicle(String brand) {
this(brand, "Unknown");
}
// Child class
class Car extends Vehicle {
private int numDoors;
public Car() {
super(); // Calls Vehicle()
this.numDoors = 4;
}
@Override
public void displayInfo() {
super.displayInfo(); // Calls Vehicle's displayInfo()
System.out.println("Number of doors: " + numDoors);
}
}
car1.displayInfo();
car2.displayInfo();
car3.displayInfo();
car4.displayInfo();
}
}
In this example:
The Vehicle class has three constructors demonstrating constructor chaining within the same
class using this().
The third and fourth call super(brand, model) to invoke the two-argument constructor
of Vehicle.
The displayInfo() method in Car overrides the one in Vehicle, calling super.displayInfo() to
reuse the parent's implementation before adding its information.
Usage in Calls another constructor in the Calls a constructor in the immediate parent
Constructors same class. class.
Syntax for
this() or this(parameters) super() or super(parameters)
Constructor Call
Position in
Must be the first statement if used. Must be the first statement if used.
Constructor
Compiler adds this implicitly Compiler doesn't add super implicitly (except
Implicit Use
when accessing instance members. default for the constructor call).
Scope Limited to the current class. Extends to the immediate parent class.
If overloading were allowed based on return type, the compiler wouldn't know which method to
call in situations where the return value is not used.
Java uses type erasure for generics, which can lead to conflicts if methods differ only by return
type.
Method overloading is resolved at compile-time based on the method signature, which doesn't
include the return type.
In Java, a method's signature consists of its name and parameter list, not the return type.
Allowing overloading by return type would break existing code and Java's commitment to
backward compatibility.
char → int
Let’s take a practical example of programs based on the automatic type promotion concept:
byte b = 25;
obj.display(b); // Promotes byte to int
short s = 30;
obj.display(s); // Promotes short to int
char c = 'A';
obj.display(c); // Promotes char to int
float f = 3.14f;
obj.display(f); // Promotes float to double
}
}
In this example:
Classes gain complete control over data members and methods This control ensures data
integrity and prevents unintended modifications.
It allows class variables to be set as read-only or write-only Tailored to specific needs, this
flexibility protects sensitive data while enabling necessary access.
Encapsulation facilitates the reuse of existing code Saving time and resources when
developing new applications.
Updating existing code is easier and less error-prone Crucial for maintaining and scaling
complex software systems.
Encapsulated code makes unit testing straightforward Leading to more reliable and
maintainable software.
Popular IDEs support getters and setters Enhancing coding efficiency and developer
productivity.
Checked exceptions
Errors
An exception is an unexpected event in a program that can be managed and recovered from
within the program itself. In contrast, an error represents a more severe condition that typically
cannot be handled within the program as it may cause damage to the system's architecture or
environment.
Compile-Time
Must be caught or declared Not required to be caught or declared
Checking
Subclasses of exception
Class Hierarchy Subclasses of RuntimeException
(excluding RuntimeException )
Method
Must be declared in a throws clause. No need to declare.
Signatures
Performance
Can have some impact. Generally, it has less impact.
Impact
Handling
Enforced by the compiler. Not enforced by the compiler.
Enforcement
Typically used with a try-catch block, the finally block ensures critical cleanup operations, like
closing files or database connections, are executed.
try {
// Code that might throw an exception
} catch (ExceptionType1 e1) {
// Handle exception of ExceptionType1
} catch (ExceptionType2 e2) {
// Handle exception of ExceptionType2
} finally {
// Code that will always execute, whether an exception occurred or not
}
Number of
Throws a single exception at a time. Can declare multiple exceptions.
Exceptions
Exception Creates and throws an actual Does not create exceptions, it just declares
Creation exception object. possibility.
Immediately transfers control to the
Execution Does not immediately affect program flow.
exception handler.
In simple terms, garbage collection refers to discarding objects no longer needed or referenced
by any other parts of the program. It's an essential aspect of how JavaScript handles memory
allocation.
Nulling the Reference: This involves explicitly setting a reference variable to null.
Anonymous Objects: These are objects created without being assigned to a reference
variable.
Objects Going Out of Scope: When a method or block ends, local variables are removed
from the stack.
void createEmployee() {
Employee e = new Employee();
Removing From Collections: Objects can become unreferenced when removed from
collections.
employees.add(new Employee());
Each of these methods can result in objects becoming unreachable from the root set, making
them eligible for garbage collection. The exact timing of when these objects are collected
depends on the JVM's garbage collection implementation and strategy.
Can be applied to variables, Used with try-catch Defined in the object class,
Usage
methods, classes. blocks. can be overridden.
Guaranteed to execute
Execution Not guaranteed to be
N/A (except in specific
Guarantee called.
cases).