What do you understand by OOP? OOP stands for object-oriented programming. It is a programming paradigm that revolves around the object rather than function and procedure. In other words, it is an approach for developing applications that emphasize on objects. An object is a real word entity that contains data and code. It allows binding data and code together.
What is the purpose of using OOPs concepts? The main purpose of OOP is to bind together the data and the functions that operate on them so that no other part of the code can access this data except that function.
The OOP has the following four features:
Inheritance Encapsulation Polymorphism Data Abstraction
Disadvantages of OOP
Proper planning is required. Program design is tricky. Programmer should be well skilled. Classes tend to be overly generalized.
What do you understand by class and object? Also, give example. Class: A class is a blueprint or template of an object. It is a user-defined data type. Inside a class, we define variables, constants, member functions, and other functionality. It does not consume memory at run time. Note that classes are not considered as a data structure. It is a logical entity. It is the best example of data binding.
Object: An object is a real-world entity that has attributes, behavior, and properties. It is referred to as an instance of the class. It contains member functions, variables that we have defined in the class. It occupies space in the memory. Different objects have different states or attributes, and behaviors.
What are the differences between class and object? Class Object It is a logical entity. It is a real-world entity. It is conceptual. It is real. It binds data and methods together into a single unit. It is just like a variable of a class. It does not occupy space in the memory. It occupies space in the memory. It is a data type that represents the blueprint of an object. It is an instance of the class. It is declared once. Multiple objects can be declared as and when required. It uses the keyword class when declared. It uses the new keyword to create an object. A class can exist without any object. Objects cannot exist without a class.
What are the manipulators in OOP and how it works?
Manipulators are helping functions. It is used to manipulate or modify the input or output stream. The modification is possible by using the insertion (<<) and extraction (>>) operators. Note that the modification of input or output stream does not mean to change the values of variables. There are two types of manipulators with arguments or without arguments.
The example of manipulators that do not have arguments is endl, ws, flush, etc. Manipulators with arguments are setw(val), setfill(c), setbase(val), setiosflags(flag). Some other manipulators are showpos, fixed, scientific, hex, dec, oct, etc.
What are the characteristics of an abstract class? An abstract class is a class that is declared as abstract. It cannot be instantiated and is always used as a base class. The characteristics of an abstract class are as follows:
Instantiation of an abstract class is not allowed. It must be inherited. An abstract class can have both abstract and non-abstract methods. An abstract class must have at least one abstract method. You must declare at least one abstract method in the abstract class. It is always public. It is declared using the abstract The purpose of an abstract class is to provide a common definition of the base class that multiple derived classes can share
Is it possible for a class to inherit the constructor of its base class? No, a class cannot inherit the constructor of its base class.
Identify which OOPs concept should be used in the following scenario? A group of 5 friends, one boy never gives any contribution when the group goes for the outing. Suddenly a beautiful girl joins the same group. The boy who never contributes is now spending a lot of money for the group.
Runtime Polymorphism
What is composition? It describes a class that references one or more objects of other classes in instance variables. It allows us to model a has-a association between objects
What is the difference between Composition and Inheritance? Inheritance means an object inheriting reusable properties of the base class. Compositions mean that an object holds other objects. In Inheritance, there is only one object in memory (derived object) whereas, in Composition, the parent object holds references of all composed objects. From a design perspective, inheritance is "is a" relationship among objects whereas Composition is "has a" relationship among objects.
What are the limitations of inheritance? The main disadvantage of using inheritance is two classes get tightly coupled. That means one cannot be used independently of the other. If a method or aggregate is deleted in the Super Class, we have to refactor using that method in SubClass. Inherited functions work slower compared to normal functions. Need careful implementation otherwise leads to improper solutions.
What are the differences between Inheritance and Polymorphism? Inheritance Polymorphism Inheritance is one in which a derived class inherits the already existing class's features. Polymorphism is one that you can define in different forms. It refers to using the structure and behavior of a superclass in a subclass. It refers to changing the behavior of a superclass in the subclass. It is required in order to achieve polymorphism. In order to achieve polymorphism, inherence is not required. It is applied to classes. It is applied to functions and methods. It can be single, hybrid, multiple, hierarchical, multipath, and multilevel inheritance. There are two types of polymorphism compile time and run time. It supports code reusability and reduces lines of code. It allows the object to decide which form of the function to be invoked at run-time (overriding) and compile-time (overloading).
What is Coupling in OOP and why it is helpful? In programming, separation of concerns is known as coupling. It means that an object cannot directly change or modify the state or behavior of other objects. It defines how closely two objects are connected together. There are two types of coupling, loose coupling, and tight coupling.
Objects that are independent of one another and do not directly modify the state of other objects is called loosely coupled. Loose coupling makes the code more flexible, changeable, and easier to work with.
Objects that depend on other objects and can modify the states of other objects are called tightly coupled. It creates conditions where modifying the code of one object also requires changing the code of other objects. The reuse of code is difficult in tight coupling because we cannot separate the code.
Since using loose coupling is always a good habit.
Name the operators that cannot be overload. Scope Resolution Operator (::) Ternary Operator (? :) Member Access or Dot Operator (.) Pointer to Member Operator (.*) sizeof operator
virtual: indicates that a method may be overridden by an inheritor
override: Overrides the functionality of a virtual method in a base class, providing different functionality.
new: Hides the original method (which doesn't have to be virtual), providing different functionality. This should only be used where it is absolutely necessary.
What is Cohesion in OOP? In OOP, cohesion refers to the degree to which the elements inside a module belong together. It measures the strength of the relationship between the module and data. In short, cohesion represents the clarity of the responsibilities of a module. It is often contrasted with coupling.
There are two types of cohesion, i.e. High and Low.
High cohesion is associated with several required qualities of software including robustness, reliability, and understandability. Low cohesion is associated with unwanted qualities such as being difficult to maintain, test, reuse, or even understand. High cohesion often associates with loose coupling and vice versa.
Is it possible to overload a constructor? Yes, the constructors can be overloaded by changing the number of arguments accepted by the constructor or by changing the data type of the parameters.
Can we overload the main() method in Java also give an example? Yes, we can also overload the main() method in Java. Any number of main() methods can be defined in the class, but the method signature must be differen
Consider the following scenario: If a class Demo has a static block and a main() method. A print statement is presented in both. The question is which one will first execute, static block or the main() method, and why?
JVM first executes the static block on a priority basis. It means JVM first goes to static block even before it looks for the main() method in the program. After that main() method will be executed.
Does constructor return any value? Ans: yes, The constructor implicitly returns the current instance of the class (You can't use an explicit return type with the constructor).
What are the restrictions that are applied to the Java static methods? Two main restrictions are applied to the static methods.
The static method can not use non-static data member or call the non-static method directly. this and super cannot be used in static context as they are non-static.
Why is the main method static? Because the object is not required to call the static method. If we make the main method non-static, JVM will have to create its object first and then call main() method which will lead to the extra memory allocation
Can we override the static methods? No, we can't override static methods.
Can we make constructors static? As we know that the static context (method, block, or variable) belongs to the class, not the object. Since Constructors are invoked only when the object is created, there is no sense to make the constructors static. However, if you try to do so, the compiler will show the compiler error.
Can we make the abstract methods static in Java? In Java, if we make the abstract methods static, It will become the part of the class, and we can directly call it which is unnecessary. Calling an undefined method is completely useless therefore it is not allowed.
Why is multiple inheritance not supported in java? To reduce the complexity and simplify the language, multiple inheritance is not supported in java. Consider a scenario where A, B, and C are three classes. The C class inherits A and B classes. If A and B classes have the same method and you call it from child class object, there will be ambiguity to call the method of A or B class.
Since the compile-time errors are better than runtime errors, Java renders compile-time error if you inherit 2 classes. So whether you have the same method or different, there will be a compile time error.
What is aggregation?
Aggregation is best described as a has-a relationship.
What is composition? Holding the reference of a class within some other class is known as composition. When an object contains the other object, if the contained object cannot exist without the existence of container object, then it is called composition. In other words, we can say that composition is the particular case of aggregation which represents a stronger relationship between two objects
What is the difference between aggregation and composition? Aggregation represents the weak relationship whereas composition represents the strong relationship. For example, the bike has an indicator (aggregation), but the bike has an engine (composition).
What are the differences between this and super keyword? There are the following differences between this and super keyword.
The super keyword always points to the parent class contexts whereas this keyword always points to the current class context. The super keyword is primarily used for initializing the base class variables within the derived class constructor whereas this keyword primarily used to differentiate between local and instance variables when passed in the class constructor. The super and this must be the first statement inside constructor otherwise the compiler will throw an error.
Can you use this() and super() both in a constructor? No, because this() and super() must be the first statement in the class constructor.
Why is method overloading not possible by changing the return type in java? In Java, method overloading is not possible by changing the return type of the program due to avoid the ambiguity.
Since i is the blank final variable. It can be initialized only once. We have initialized it to 20. Therefore, 20 will be printed.
What are design patterns? Design patterns are the reusable solutions that solve common problems of software development. These problems include repetitive code, redundant functions and logic etc. These help to save considerable effort and time required for the developers while developing software. Design patterns are commonly used in object-oriented software products by incorporating best practices and promoting reusability for developing robust code.
How are design patterns different from algorithms? Both Design Patterns and Algorithms describe typical solutions to any given problem. But the main difference is that the algorithm defines a clear set of actions for achieving a goal and a design pattern provides a high-level description of any solution. Design patterns applied to two different problems might be the same but the logic of implementation would be different and is based on the requirements
How are design principles different from design patterns? Design principles are those principles that are followed while designing software systems for any platform by making use of any programming language. SOLID principles are the design principles that we follow as guidelines to develop robust, extensible and scalable software systems. These apply to all aspects of programming.
Design Patterns are the reusable template solutions for commonly occurring problems that can be customized as per the problem requirements. These are well-implemented solutions that are tested properly and are safe to use. Factory Design Pattern, Singleton pattern, Strategy patterns are a few of the examples of design patterns.
What are some of the design patterns used in Java’s JDK library? Following are some design patterns used in Java’s JDK library:
Decorator pattern are used by the Wrapper classes. Singleton pattern is used in classes like Calendar and Runtime. Factory pattern is used for methods like Integer.valueOf methods in wrapper classes. Observer pattern is used for handling event frameworks like awt, swing etc.
For experienced:
What is the main advantage of using a prototype design pattern over object creation using a new keyword? Prototype design pattern is used for creating duplicate objects based on the prototype of the already existing object using cloning. Doing this has a positive impact on the performance of object creation. Creating objects using the new keyword requires a lot of resources and is a heavyweight process that impacts performance. Hence, the prototype design pattern is more advantageous than the object created using a new keyword.
What is Decorator Design Pattern? Decorator design pattern belongs to the category of structural pattern that lets users add new features to an existing object without modifying the structure. This pattern creates a class called decorator class that acts as a wrapper to the existing class by keeping the signatures of class methods intact. This pattern makes use of abstract classes and interfaces with composition for implementing the wrapper. They are mostly used to apply SRP (Single Responsibility Principle) as we divide functionalities into classes with unique concerns. This pattern is structurally similar to the chain of responsibility pattern. Following are the steps to implement decorator design pattern:
- Create an interface and concrete classes that implement this interface.
- Create an abstract decorator class that implements the above interface.
- Create a concrete decorator class that extends the above abstract class.
- Use the concrete decorator class to decorate the interface objects and verify the output. Let us understand this with the help of an example. Here, we will be creating a Shape Interface and concrete classes- Rectangle and Triangle that implement this Shape interface. We will be creating an abstract decorator class “ShapeDecorator” that implements the Shape interface. We will create RedColorDecorator that extends ShapeDecorator. We will be then using this decorator to implement the functionalities.
What is a Command pattern? The command pattern is a type of behavioural design pattern that transforms a request into a stand-alone object containing all the details about the request. This pattern is a data-driven pattern because we make use of the information about the request by wrapping it as an object and is passed to the invoker object as a command. The invoker object checks for the object that can handle the command and passes it to that object to execute the command.
What is an Observer Design Pattern? An observer design pattern is a type of behavioural design pattern that is used for defining the one to many dependencies between the objects. It is most useful when we want to get notified about any change in the state of an object. In this pattern, when the state of one object changes, all the dependent objects are notified automatically. The object whose state is monitored is called the Subject whereas the dependents are called the Observers
This design pattern has 3 main components:
Subject - This can be an interface or an abstract class that defines operations for attaching (registerObserver()) and detaching the observers (removeObserver()) to the subject. Concrete Subject - This is a concrete class of the Subject. This maintains the object state and whenever any change occurs in that state, the observers are notified about it using notifyObservers() method. Observer - This is an interface or an abstract class that defines the operations for notifying this object (update()). One real work example of this pattern is Facebook or Twitter. Whenever a person updates the status, all the followers would get a notification about his update. An observer can get the notification of the subject as long as it is subscribed or keeping track of it.
What problem does Builder Pattern try to solve? A builder pattern is a type of creational design pattern that lets to construct complex objects in a step by step manner. The pattern lets to produce different representations of an object using the same construction logic. It helps in creating immutable classes having a large set of attributes. In the Factory and Abstract Factory Design Patterns, we encounter the following issues if the object contains a lot of attributes:
When the arguments are too many, the program will be error-prone while passing from the client to the Factory Class in a specific order. It becomes tedious to maintain the order of arguments when the types are the same. There might be some optional attributes of the object and yet we would be forced to send all parameters and optional attributes as Null. When the object creation becomes complex due to heavy attributes, the complexity of this class would become confusing. The above problems can also be solved by using constructors of required parameters alone. But this causes an issue when there would be new parameters that are added as part of new requirements. This would result in inconsistency. That’s where Builder comes into the picture. This pattern solves the issue of a large number of optional attributes and the inconsistent state by providing means to build an object in a step-by-step way and return the final object utilizing another method.
Builder pattern can be implemented by following the below steps:
Create a static nested class, copy all arguments from the outer class. This nested class would be called the Builder class. Proper naming convention has to be followed while naming this builder class. For example, if the name of the class is Interviewbit, then the name of the builder would be InterviewbitBuilder. The builder class should have a public constructor with all required attributes sent as parameters. The builder class should have methods for setting optional parameters and return the same builder object post setting these values. The last step is to have a build() method inside the builder class that returns the Object needed by the client. This would require a private constructor in the class that takes the Builder class as the parameter.
What do you understand by the Null Object pattern? In this pattern, a null object is used for replacing the check of validating if the object instance is null or not. This Null Object has a “do nothing” relationship and these can be used for providing default behaviour if the data is unavailable.
What is the MVC design pattern? MVC stands for Model-View-Controller. This pattern is used for separating the application’s concerns as listed below:
Model - This represents the object (Java POJO) that carries the data. It can also consist of the logic of updating the controller in case the data changes. View - This represents the data visualization of the model. Controller - This is an interface between the Model and the View by controlling the flow of data into the model and updating the view whenever the model gets updated. This ensures that the model and the views are kept separate.
What is a Chain of Responsibility pattern? In what scenarios to apply this pattern? Chain of Responsibility belongs to the category of a behavioural design pattern that passes requests via a chain of handlers. Whenever a request is received, the handler decides whether to process the request or pass it to the next handler of the chain. It is used for achieving loose coupling where the client request is passed through an object chain to process them.
There are 3 components of this design, they are:
Client: This is the point of request origination and the component that accesses the handler for handling the request. Handler: Handler can either be a class or an interface that received the request primarily and dispatches it to the chain of handlers. This Handler knows only the first handler of the chain. Concrete Handlers: These are the actual request handlers in sequential order.
How can you achieve thread-safe singleton patterns in Java?
Using Enums: Enums are the simplest means of creating a thread-safe singleton class in Java because the synchronization support is inherently done by Java itself. Enums are by default final and this also helps in preventing multiple initializations at the time of serialization.
Using Static Field Initialization: Thread-safe singleton can also be created by creating the instance at the time of class loading. This is achieved by making use of static fields as the Classloader guarantees that the instances are initialized during class loading and the instance is not visible until that has been fully created.
Using synchronized keyword: We can make use of the synchronized keyword upon the getInstance method as shown below. In this method, we can achieve lazy initialization, and also since we use synchronized keywords, the object initialization is thread-safe. The only problem is that since the whole method is synchronized, the performance is impacted in the presence of multiple threads.
Double-check locking: Here, we will be using a synchronized block of code within the getInstance method instead of making the whole method synchronized. This ensures that only a handful of threads have to wait only for the first time thereby not impacting the performance.
public static ThreadSafeSingleton getInstance(){
if (instance == null){
//synchronized block of code
synchronized (ThreadSafeSingleton.class){
if(instance==null)
{
// initialize only if instance is null
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
What are some instances where we prefer abstract classes over interfaces in Java? Both Abstract classes and interfaces in Java follow the principle of writing code for interface rather than the implementation. This principle ensures that flexibility is added to the code to tackle dynamic requirements. Some of the pointers for deciding what to prefer over what are as follows:
Java lets to extend only one class and let’s implement multiple interfaces. If we extend one class then we cannot extend other classes. In such cases, it is better to implement the interfaces wherever possible and reserve the inheritance of classes to only important ones. Interfaces are used for representing the behaviour of the class. Java lets to implement multiple interfaces which is why we can take the help of interfaces to help classes have multiple behaviours at the same time. Abstract classes are slightly faster than interfaces. It can be used for time-critical applications. In cases where there are common behaviours across the inheritance hierarchy, these can be coded at one place in abstract classes. Interfaces and abstract classes can also be used together to define a function in interface and functionality in abstract class.
What is a Bridge Design Pattern? The bridge pattern is a type of structural design pattern that lets to split large class or closely related classes into 2 hierarchies - abstraction and implementation. These hierarchies are independent of each other and are used whenever we need to decouple an abstraction from implementation. This is called a Bridge pattern because it acts as a bridge between the abstract class and the implementation class. In this pattern, the abstract classes and the implementation classes can be altered or modified independently without affecting the other one.
There are 4 main elements of Bridge Pattern. They are:
Abstraction – This is the core of the pattern and it defines its crux. This contains a reference to the implementer. Refined Abstraction – This extends the abstraction and takes refined details of the requirements and hides it from the implementors. Implementer – This is the interface for the implementation classes. Concrete Implementation – These are the concrete implementation classes that implement the Implementer interface.
What is a Proxy Design Pattern? Proxy design pattern falls under the category of structural design that represents the functionality of other classes. This pattern lets the developers provide a substitute for another object. This is called a proxy object. This helps to control the access to the original object and allows us to perform many tasks before or after the request reaches the original object.
What is an Adapter Design Pattern? The adapter design pattern falls under the category of a structural design pattern that lets incompatible objects collaborate. It acts as a wrapper between 2 different objects. The adapter catches the call for one object and transforms them to be recognizable by the second object.
What is a Factory Design Pattern? Factory design pattern belongs to the category of Creational Design Patterns. Here, the objects are created without exposing the logic of creation to the client. The objects refer to the common interface.
//More to learn Facade pattern Delegation pattern
SOLID:::
What are the SOLID Principles? S - Single Responsibility Principle (SRP): The single responsibility principle ensures that every class or module should be accountable and responsible for only one functionality. There should be one and only one reason for changing any class. O - Open Closed Principle (OCP): Every class is open for extension but closed for modification. Here, we are allowed to extend the entities behaviour by not modifying anything in the existing source code. L - Liskov Substitution Principle(LSP): LSP principle states that the objects can be replaced by the subtype instances without affecting the correctness of the program. I - Interface Segregation Principle (ISP): The ISP principle states that we can use as many interfaces specific to the client’s requirements instead of creating only one general interface. Clients should not be forced to implement the functionalities that they do not require. D - Dependency Inversion Principle: Here, the high-level modules should not be dependent on the lower level modules or concrete implementations. Instead, they should be dependent on the abstractions.
Benefits of using SOLID principles Clean: SOLID principles make code clean and standard code. Maintainable: with the help of SOLID principles our code becomes more manageable and easy to maintain. Scalable: Easy to refactor or change code. Redundancy: SOLID principles avoid redundant code. Testable: can be easily unit tested. Readable: SOLID principles make the code easy and readable. Independent: code becomes independent by reducing dependencies. Reusable: code becomes reusable.
What do you understand by the Open-Closed Principle (OCP)? The Open close principle states that any class, component or entity should be open for extension but closed for modification. A class can be extended via Inheritance, Interfaces, Composition whenever required instead of modifying the code of the class. Consider an instance where we have a class that calculates the area of a square. Later, we get the requirement of calculating the area of a rectangle. Here, instead of modifying the original class, we can create one base class and this base class can be extended by the new class rectangle.
Reference: https://www.interviewbit.com/design-patterns-interview-questions/