Oops Questions
Oops Questions
1. What is OOPs?
It is a programming paradigm that is used to develop software applications by creating
objects that interact with each other.
In simple terms, OOP is a way of writing software that models real-world objects, such as
people, cars, or buildings, as software objects with specific properties and behaviour.
The main idea behind OOP is to create reusable code that can be modified and extended
with ease. It allows programmers to write code that is easier to read, understand, and
maintain.
This allows objects to be used and manipulated without revealing their internal workings.
Encapsulation is achieved by defining the object's attributes as private or protected, and
providing public methods to access and modify those attributes.
b) Inheritance
It is the process of creating new classes from existing classes. It allows a new class to inherit
properties and behaviour from an existing class.
The existing class is known as the superclass or parent class. The new class is known as
the subclass or child class.
c) Polymorphism
It is the ability of an object to take on multiple forms. It allows different objects to be used
interchangeably, even though they may have different implementations. Polymorphism can
be achieved through method overloading and method overriding.
d) Abstraction
It is the process of simplifying complex systems by modelling them at a high level. In OOP,
abstraction is achieved by creating abstract classes and interfaces that define the methods
that must be implemented by their subclasses.
This allows the programmer to focus on the essential features of the system, while ignoring
the irrelevant details.
It is essentially a user-defined data type that encapsulates data (in the form of fields or
properties) and behaviour (in the form of methods). The fields or properties define the
characteristics of the object, while the methods define what the object can do.
Example of class
Let's consider a class called "Car". This class may have fields such as "make", "model",
"year", and "color", which define the characteristics of a car object.
It may also have methods such as "start", "stop", "accelerate", and "brake", which define the
behaviour of a car object.
Once a class has been defined, it can be used to create multiple instances or objects of that
class. Each object will have its own set of values for the fields or properties, and will be able
to perform the methods defined by the class.
When an object is created, it has its own unique set of properties and methods based on the
definition of its class. These properties and methods can be accessed and manipulated
through the object's public interface, which consists of its public methods and properties.
Example of object
Consider the class "Car". An object of the Car class can be created by instantiating the
class, like this:
In this case, myCar is an object of the Car class. It has its own set of properties (such as
make, model, year, and color) and methods (such as start, stop, accelerate, and brake) that
are defined by the Car class. These properties and methods can be accessed and
manipulated using dot notation, like this:
myCar.color = "red";
myCar.start();
Inheritance is the process of creating a new class (called the subclass or child class) from an
existing class (called the superclass or parent class).
The subclass inherits properties and behaviours from its superclass, and can also add new
properties and behaviours or modify existing ones.
The basic idea behind inheritance in OOP is to create a hierarchy of classes with increasing
levels of specialisation. The most general class in the hierarchy is the superclass, which
defines the basic properties and behaviours that are shared by all its subclasses. Each
subclass can then add more specific properties and behaviours that are unique to it.
Consider a class hierarchy that includes a superclass called "Vehicle" and two subclasses
called "Car" and "Motorcycle". The Vehicle class may have properties such as "make",
"model", "year", and "color", as well as methods such as "start" and "stop" that are common
to all types of vehicles.
The Car subclass may inherit these properties and methods from the Vehicle class, but also
add its own properties, such as "numDoors" and methods such as "getGasMileage". The
Motorcycle subclass may also inherit from Vehicle, but may have its own unique properties
such as "numWheels" and methods such as "lean".
The idea behind encapsulation is to protect the internal state of an object from being
modified directly by external code, and to enforce the use of the public interface for any
interactions with the object. This helps to prevent errors and ensure that the object is used
correctly.
Example of encapsulation
Consider a class called "BankAccount". This class may have private fields such as "balance"
and "accountNumber", which should not be modified directly by external code. Instead, the
class may provide public methods such as "deposit", "withdraw", and "getBalance" for
interacting with the account.
Abstraction helps to manage complexity by hiding the underlying details of a system and
presenting only the essential features that are relevant to the user. This allows the user to
interact with the system at a higher level of abstraction, without having to worry about the
low-level details.
An abstract class may contain one or more abstract methods, which are defined but not
implemented in the abstract class. The subclasses of the abstract class must implement
these abstract methods to provide concrete functionality.
Example
For example, consider a class hierarchy that includes a superclass called "Animal" and two
subclasses called "Dog" and "Cat".
The Animal class may have abstract methods such as "makeSound" and "move", which are
implemented differently in each subclass. The Dog subclass may implement the
"makeSound" method as "bark" and the "move" method as "run", while the Cat subclass may
implement the "makeSound" method as "meow" and the "move" method as "walk".
It enables the same code to work with different objects in different ways, depending on their
actual type or class.
When an overloaded method is called, the compiler determines which method to call based
on the number, type, and order of the arguments passed to the method. The method name
and the number, type, and order of the parameters must be different in each overloaded
method.
The first method takes two integers as arguments and returns their sum, while the second
method takes two doubles as arguments and returns their sum.
When we call the "add" method with two integers, the first method is called, and when we
call the "add" method with two doubles, the second method is called.
When we call the "speak" method on a Dog object, the overridden method in the Dog class
is called, and when we call the "speak" method on an Animal object, the original method in
the Animal class is called.
In Java, a constructor has the same name as the class and does not have a return type, not
even void. It is called implicitly when an object is created using the "new" keyword, and it can
also be called explicitly like any other method.
a) Default constructor
This constructor is provided by Java if a class does not have any constructors explicitly
defined. It takes no parameters and initialises all the data members to their default values
(e.g., null for object references, 0 for integers, etc.).
b) Parameterized constructor
This constructor is defined by the programmer and takes one or more parameters. It
initialises the data members with the values passed as arguments.
In other programming languages, such as C++, destructors are used to free up memory that
was allocated using the "new" operator. When an object is created using the "new" operator,
memory is allocated for it on the heap. When the object is no longer needed, its destructor is
called, and the memory is freed up.
Here, the "incrementCount" and "getCount" methods are declared as static. This means that
you can call them on the "MyClass" class without creating an instance of it first.
MyClass.incrementCount();
int count = MyClass.getCount();
Static methods are often used to provide utility methods that don't require an instance of the
class to be created. They can also be used to define constants that are associated with the
class rather than with any particular instance of the class.
Static methods cannot access non-static variables or methods because they are not
associated with any instance of the class.
15. What is a static variable?
In Java, a static variable is a variable that belongs to the class rather than to any instance of
the class. This means that all instances of the class share the same static variable, and
changes to the static variable by one instance will be visible to all other instances.
Here, the "count" variable is declared as static. This means that it belongs to the "MyClass"
class rather than to any instance of the class.
Here, both "obj1" and "obj2" share the same "count" variable. When "incrementCount" is
called on each instance, the value of "count" is incremented. When "getCount" is called on
each instance, it returns the same value because they are both accessing the same static
variable.
The main difference between them is that instance variables are associated with an instance
of a class, while class variables are associated with the class itself.
Key differences between instance variables and class variables:
a) Scope
Instance variables are only accessible within the instance of the class in which they are
defined, whereas class variables are accessible throughout the entire class.
b) Lifetime
Instance variables are created when an instance of the class is created and are destroyed
when the instance is destroyed, whereas class variables exist for the entire lifetime of the
program.
c) Memory allocation
Instance variables are allocated memory each time an instance of the class is created,
whereas class variables are allocated memory only once when the class is loaded.
d) Sharing
Each instance of a class has its own copy of instance variables, while class variables are
shared by all instances of the class.
A package is declared at the beginning of a Java source file, using the "package" keyword
followed by the name of the package. For example, the following code declares a package
named "com.example":
package com.example;
Classes and interfaces can then be declared within this package, like this:
package com.example;
public class MyClass {
// class members here
}
interface MyInterface {
// interface members here
}
To use a class or interface from a package in another Java source file, you need to import it
using the "import" keyword.
For example, to use the "MyClass" class from the "com.example" package in another file,
you would add the following import statement:
import com.example.MyClass;
Packages can also contain sub-packages, which can be used to further organise classes
and interfaces. For example, the following code declares a package named
"com.example.util" which is a sub-package of the "com.example" package:
package com.example.util;
Packages can also be used to control access to the members of classes and interfaces. By
default, all members of a class or interface are accessible from within the same package.
However, you can use access modifiers such as "public", "private", and "protected" to control
the visibility of members from outside the package.
● Encapsulation
● Inheritance
● Polymorphism
● Abstraction
a) Final variables:
A final variable is a variable whose value cannot be changed once it is initialised. It is also
called a constant. A final variable can be initialised during declaration or in a constructor.
Once initialised, its value cannot be modified.
Example:
b) Final methods:
A final method is a method that cannot be overridden by a subclass. When a method is
marked as final, its implementation is fixed and cannot be changed by a subclass.
Example:
c) Final classes:
A final class is a class that cannot be extended by any subclass. When a class is marked as
final, it cannot be subclassed.
Example:
When you create an instance of this class, each instance will have its own copy of
"instanceVar", but they will all share the same "classVar". For example:
Here, "obj1" and "obj2" have different values for their instance variable "instanceVar", but
they share the same value for their class variable "classVar". When "setClassVar" is called
on "obj1", it sets the value of the class variable to 10, which is then shared by all instances of
the class.
a)Static polymorphism
Also known as compile-time polymorphism, the static polymorphism in OOP is achieved
through method overloading.
Method overloading allows multiple methods to have the same name, but with different
parameters or argument types. The compiler figures out which method to call on the basis of
number, type, and order of the arguments passed to the method.
b) Dynamic polymorphism
Also known as runtime polymorphism, the dynamic polymorphism is achieved through
method overriding.
Method overriding allows a subclass to provide its own implementation of a method that is
already defined in its superclass. When a method is called on an object, the runtime
environment determines which implementation of the method to call based on the actual
type of the object at runtime.
A static method cannot use the this An instance method can use
Use of this
keyword as it does not belong to an the this keyword to refer to the
keyword
instance of a class. current instance of the class.
25. What is a design pattern, and can you name a few commonly
used design patterns?
A design pattern is a general, reusable solution to a commonly occurring problem in software
design. Design patterns provide a template for solving problems in software development
and help to create flexible, maintainable, and reusable software architectures.
a) Singleton Pattern:
This pattern ensures that a class has only one instance, and provides a global point of
access to that instance.
b) Factory Pattern:
This pattern provides an interface for creating objects, but allows subclasses to alter the type
of objects that will be created.
c) Observer Pattern:
This pattern defines a one-to-many relationship between objects, so that when one object
changes state, all its dependents are notified and updated automatically.
d) Decorator Pattern:
This pattern allows behaviour to be added to an individual object, either statically or
dynamically, without affecting the behaviour of other objects from the same class.
e) Strategy Pattern:
This pattern defines a family of algorithms, encapsulates each one, and makes them
interchangeable.
f) Adapter Pattern:
This pattern converts the interface of a class into another interface that clients expect. It
allows incompatible classes to work together by wrapping one class with another class that
has a compatible interface.
g) Facade Pattern:
This pattern provides a unified interface to a set of interfaces in a subsystem. It defines a
higher-level interface that makes the subsystem easier to use.
● It has a private constructor to prevent the creation of new instances of the class from
outside the class.
● It has a private static instance variable that holds the single instance of the class.
● It has a public static method that returns the single instance of the class.
Here, the Singleton class has a private constructor to prevent the creation of new instances
of the class. It has a private static instance variable that holds the single instance of the
class, and a public static method getInstance() that returns the single instance of the class.
The getInstance() method checks if an instance of the class has already been created. If it
hasn't, it creates a new instance and returns it. If an instance already exists, it returns the
existing instance.
Here, the "Person" class has a constructor that takes two parameters: "name" (a string) and
"age" (an integer). When an object of the "Person" class is created using this constructor, its
"name" and "age" data members are initialised with the values passed as arguments.
● It has a Factory interface that declares a factory method for creating objects.
● It has a ConcreteFactory class that implements the Factory interface and creates
objects of a particular type.
● It has a Product interface that defines the interface for the objects that the factory
method creates.
● It has ConcreteProduct classes that implement the Product interface and provide the
implementation for the objects that the factory method creates.
Here, the Animal interface defines the interface for the objects that the factory method
creates. The Dog and Cat classes implement the Animal interface and provide the
implementation for the objects that the factory method creates.
The AnimalFactory interface declares a factory method for creating objects, and the
DogFactory and CatFactory classes implement the AnimalFactory interface and create
objects of the Dog and Cat classes, respectively.
The three most commonly used access modifiers are private, protected, and public.
a) Private:
Members declared as private can only be accessed within the same class. They are not
visible to any other class, including subclasses.
This is the most restrictive access level and is often used to protect sensitive data or to
prevent unintended modifications to class members.
b) Protected:
Members declared as protected can be accessed within the same class, subclasses, and
other classes in the same package.
They are not visible to classes in different packages, except through inheritance. This
access level is less restrictive than private but more restrictive than public.
c) Public:
Members declared as public can be accessed from any class or package. This is the least
restrictive access level and is often used for methods and variables that are part of the
class's public interface.
Private Yes No No No
Answer: a
Answer: e
Answer: b
Answer: c
Answer: c
Answer: a
Answer: a
Answer: a
Answer: a