
1. Questions on OOP Core Concepts
Java OOP interview questions guide lists some important and tricky questions and answers to help refresh the basic concepts with examples.
1. Questions on OOP Core Concepts
1.1 What are the four major pillars of OOP?
The major pillars on which OOP relies are Encapsulation, Inheritance, Polymorphism and Abstraction.
Encapsulationprovides security to our application, it consists of private variable declarations (data hiding) and accessor methods (getters/setters) to access the variables.Inheritancereduces code redundancy by providing code reusability.Polymorphismprovides flexibility any allowing to the declaration of methods with the same name for different purposes.Abstractionprovides security by hiding the internal implementation of a class and only exposing the details necessary in the context.
1.2. Is Java a pure object-oriented programming language?
No, Java is not a pure object-oriented programming langeuage because:
Java does not provide multiple inheritance support for classes.
Java does not provide support for operator overloading.
We use primitive variables like byte, short, char, int, float, long and double these are not object.
Because of the above reasons, we can't say Java is 100& pure object-oriented.
1.3. What are the tightly encapsulated and loosely encapsulated classes?
A tightly encapsulated class does not allow public access to any of its data members and only allows accessors and mutator methods to modify them. In general, we can say a class is tightly encapsulated if and only if every variable indide the class is private scoped.
Note that an immutable class is always tightly encapsulated, but not every tightly encapsulation class is immutable.
public class Student {
private int rollNo;
private String studentName;
private String collageName;
//Getters and Setters
}Characteristics of Tightly Encapsulated Classes:
Private Fields: All instance variables (fields) are deciared
private.Controlled Access: Access to fields is provided through public getter and setter methods (or only getters for read-only fields).
Data Hiding: Internal representation and state are hidden from other classes, making the class less prone to errors caused by unintended external modifications.
Improved Security: Since the internal data cannot be directly accessed or modified from outside the class, in enhances security and protects the data from unauthorzized access.
If an least one variable indide the class is not declared private. Instead, they may be protected, public, or package-private (default). This allows for more direct access to the fields from outside the class, which may be appropriate in some cases but can make the class less secure and more prone to errors then that class is known as a loosely encapsulation class.
public class Student {
private int rollNo;
private String studentName;
String collageName;
//Getters and Setters
}Characteristics of Loosely Encapsulated Classes:
Public or Protected Fields: Some or all fields are marked as public or protected, allowing direct access from other classes.
Less Control: There is less control over how the fields are accessed or modified, leading to potential unintended side effects or errors.
Reduced Data Hiding: Internal representation and state are exposed to other classes, which may reduce modularity and increase coupling.
Flexibility Over Security: Loosely encapsulated classes offer more flexibility but at the cost of reduced security and data protection.
1.4. What are Coupling and Cohesion?
Coupling is the degree of dependency between the components.
Tight coupling generally happens when a class knows too much the internal working of the dependent classes. Many times, we cannot change one component without changing the other.
In the following example, we use the ReportService class that prepares the data and writes a PDF report using the PdfReportWriter instance. Suppose we want to add the capability to write excel reports as well. Can we add the capability without changing the ReportService? NO
public class ReportService {
public Object[][] createReportData() {...}
private writeReport(Object[][] data) {
new PdfReportWriter().writeData(data);
}
}In a loosely coupled system, components depend on each other to the least extent practically possible. This allows us to change individual components without affecting other parts of the software.
In the following code, we solved the previous problem using low coupling. Now the ReportService class only expects an IReportWriter implementation, and that class would be responsible for generating the report. We can inject as many supported report types, without touching any of the other classes.
public interface IReportWriter {
public void writeData(Object[][] data);
}
public class PdfReportWriter implements IReportWriter {
public void writeData(Object[][] data) {...}
}
public class ExcelReportWriter implements IReportWriter {
public void writeData(Object[][] data) {...}
}
public class ReportWriter implements IReportWriter {
IReportWriter writer;
public Object[][] createReportData() {...}
private writeReport(Object[][] data) {
writer.writeData(data);
}
}Cohesion is creating components with clear well-defined responsibilities. If we maintain only one component for all functionalities, then it's known as low cohesion and has several disadvantages.
public class AppManager {
public void login(){...}
public void register(){...}
public void forgotPassword(){...}
public void addToCart(){...}
public void checkout(){...}
}Maintaining high cohesion by creating defferent components for different functionality is always a good programming practice.
public class LoginManager {
public void login(){...}
}
public class RegistrationManager {
public void register(){...}
}
...
...The above program follows low cohesion as every functionality is declared inside only one component. We can achieve low cohesion by following the Single responsibility principle.
Note
It is highly recommended to follow loose coupling and high cohesion always.