Chapter 14: Object-Oriented Programming (OOP)
Table of contents
- Introduction
- 1. Classes and Objects
- 2. Access Modifiers
- 3. Getters and Setters
- 4. Encapsulation
- 5. Constructor
- 6. Types of Constructors
- 7. Copy Constructor
- 8. Shallow and Deep Copy
- 9. Destructor (Finalizer in Java)
- 10. Inheritance
- 11. Single-Level Inheritance
- 12. Multilevel Inheritance
- 13. Hierarchical Inheritance
- 14. Hybrid Inheritance
- 15. Polymorphism
- 16. Method Overloading
- 17. Method Overriding
- 18. Packages in Java
- 19. Abstraction
- 20. Abstract Classes
- 21. Interfaces
- 22. Static Keyword
- 23. Super Keyword
- 24. Solved Practice Questions
- 25. Assignment Solve
Continuing the DSA Series: A Deep Dive into OOP
In this chapter of the DSA series, we move beyond data structures and algorithms and delve into one of the most important paradigms in programming: Object-Oriented Programming (OOP). OOP plays a crucial role in building scalable and maintainable software. In this chapter, we will explore the fundamental concepts of OOP, which are essential for both understanding Java and advancing your software development skills. This chapter will cover the theory, examples, and explanations needed to master these concepts.
Introduction
This chapter is important in terms of interview preparation. While you might not face direct coding questions from this chapter, interviewers often ask about definitions and core OOP concepts. Object-Oriented Programming (OOP) revolves around using classes and objects to structure code, which leads to writing good, maintainable, and scalable code.
When you apply OOP in real-world projects, you model real-world entities like animals, pens, or even complex systems like companies. These real-world entities and their properties are translated into classes and objects in the code. A solid understanding of these concepts enables you to solve problems in a structured way.
1. Classes and Objects
Objects: Representing Real-World Entities
Let’s start with objects. Objects are entities that represent real-world things like animals, cars, or pens. When we write code for a company or a project, we often solve real-world problems, so it makes sense to represent real-world things in our programs.
For example, a Pen is an object in the real world that has properties such as color and tip size. It also has behaviors (or functions) such as changing the color or changing the tip size. In programming, an object behaves in the same way, encapsulating both properties (data) and functions (actions) together.
To represent this in code, we need a way to model it, which leads us to the next concept: classes.
Classes: Blueprints for Objects
A class is essentially a blueprint for creating objects. Think of a class as a template that defines what an object will look like and how it will behave.
For example, before you manufacture a car, you first need a blueprint that tells you the specifications of the car—its shape, dimensions, engine type, etc. Similarly, in programming, before creating an object like a car, we define a class that serves as the blueprint for that object.
Once you have a class, you can create many objects from it, just like you can manufacture many cars using the same blueprint. Each object created from a class is a unique instance with its own set of data, but all instances share the same structure defined by the class.
Here’s how it works:
A class defines the attributes (also known as properties) and the methods (also known as behaviors) that describe what the object is and what it can do.
An object is a specific instance of that class, with actual values assigned to its attributes.
Example: Pen Class
Let’s understand this better with a practical example using a Pen. In real life, a pen has certain attributes (e.g., color, tip size) and functions (e.g., the ability to change color or tip size). To model this in programming, we first create a class that defines these properties and behaviors.
Pen Class Structure:
Attributes (Properties):
color
(e.g., "Blue", "Black")tip
(e.g., 5, 6)
Methods (Behaviors):
setColor()
: A method to change the color of the pen.setTip()
: A method to change the tip size of the pen.
By convention, the name of the class starts with a capital letter (e.g., Pen
). Now, let’s look at how this class can be defined in Java.
class Pen {
// Attributes (Properties)
String color;
int tip;
// Method to set the pen's color
void setColor(String newColor) {
color = newColor;
}
// Method to set the pen's tip size
void setTip(int newTip) {
tip = newTip;
}
}
In the code above, we define the Pen
class with two attributes (color
and tip
) and two methods (setColor()
and setTip()
) that allow us to modify these attributes. This is just the blueprint of a pen—it doesn’t create an actual pen yet.
Creating Objects from a Class
To create an actual pen that we can use, we need to create an object from the Pen class. When we create an object, it takes up space in memory, and we can interact with its properties and methods. Objects in Java are stored in a part of memory called the heap.
To create an object in Java, we use the new
keyword followed by a call to the class's constructor method. Here’s how to create a pen object and set its attributes:
public class Basic {
public static void main(String[] args) {
Pen p1 = new Pen(); // Create an object of the Pen class
p1.setColor("Blue"); // Set the pen color
p1.setTip(6); // Set the pen's tip size
// Print the pen's attributes
System.out.println(p1.color); // Output: Blue
System.out.println(p1.tip); // Output: 6
// Change the pen's color directly (not recommended, but possible)
p1.color = "Yellow";
System.out.println(p1.color); // Output: Yellow
}
}
In this example:
Pen p1 = new Pen();
creates a new Pen object,p1
. This object is stored in the heap memory, and a reference to it is held in the variablep1
.p1.setColor("Blue");
sets the pen's color to blue, andp1.setTip(6);
sets the tip size to 6.The
System.out.println()
statements are used to print the current values ofcolor
andtip
.While you can directly modify the attributes (e.g.,
p1.color = "Yellow";
), this is not recommended because it bypasses the encapsulation provided by methods likesetColor()
.
A More Detailed Example
Let’s now expand on this example with another class: Student. Just like we modeled a pen, we can model a student with properties such as name and age, and behaviors such as calculating grades based on exam scores.
class Student {
String name;
int age;
// Method to calculate the percentage from subject scores
void calculatePercentage(int phy, int chem, int maths) {
int percentage = (phy + chem + maths) / 3;
System.out.println("Percentage: " + percentage + "%");
}
}
In this Student class:
The attributes are
name
andage
.The method
calculatePercentage()
takes the scores of three subjects (Physics, Chemistry, and Mathematics) and calculates the percentage.
To create a Student object and use this method, you would write:
public class Basic {
public static void main(String[] args) {
// Creating a Student object
Student student1 = new Student();
student1.name = "Rohit"; // Setting the name
student1.age = 20; // Setting the age
// Calculating and printing the percentage
student1.calculatePercentage(85, 90, 80); // Output: Percentage: 85%
}
}
Here, we create a Student
object student1
, set its name and age, and then call the calculatePercentage()
method to compute and print the student’s exam percentage.
By using classes and objects, we can effectively model real-world entities in our programs. Each class serves as a blueprint for the object it represents, and each object is a specific instance with its own properties and behaviors. Through this, we can write modular, reusable, and maintainable code.
In interviews, understanding these concepts thoroughly—how to define a class, create objects, and use methods—forms the foundation for more advanced topics in Object-Oriented Programming (OOP), such as inheritance, polymorphism, and encapsulation.
2. Access Modifiers
Access modifiers in Java control the visibility of class members (fields, methods, and constructors). The main access modifiers are:
private: Accessible only within the same class.
default: Accessible within the same package.
protected: Accessible within the same package and by subclasses.
public: Accessible from any class.
3. Getters and Setters
Getters and setters are methods used to retrieve (get) and modify (set) the value of private fields in a class, ensuring encapsulation.
Example:
class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
4. Encapsulation
Encapsulation refers to bundling data (fields) and methods that operate on that data into a single unit (class), and restricting direct access to some components, which is achieved through access modifiers.
5. Constructor
A constructor is a special method in a class that is called when an object is created. It initializes the object's fields.
Example:
class Dog { String name; Dog(String name) { this.name = name; } }
6. Types of Constructors
In Java, there are two main types of constructors:
Default constructor: Provided by the compiler if no other constructor is defined.
Parameterized constructor: Allows object creation with specific values.
7. Copy Constructor
A copy constructor creates a new object by copying the data of an existing object.
Example:
class Book { String title; Book(Book b) { this.title = b.title; } }
8. Shallow and Deep Copy
Shallow copy: Copies the object's reference, not the actual data.
Deep copy: Copies all the fields, recursively copying the objects.
9. Destructor (Finalizer in Java)
Java does not have destructors like C++. Instead, it uses a method called finalize()
, which is called before an object is garbage collected.
10. Inheritance
Inheritance is a mechanism where one class (child class) inherits properties and behaviors from another class (parent class).
11. Single-Level Inheritance
In single-level inheritance, a class inherits from only one parent class.
12. Multilevel Inheritance
In multilevel inheritance, a class is derived from a class that is already derived from another class.
13. Hierarchical Inheritance
In hierarchical inheritance, multiple classes inherit from a single parent class.
14. Hybrid Inheritance
Hybrid inheritance is a combination of multiple and multilevel inheritance. However, Java doesn’t directly support multiple inheritance with classes, but it can be achieved using interfaces.
15. Polymorphism
Polymorphism allows one entity to take multiple forms. It can be achieved via method overloading and overriding.
16. Method Overloading
Method overloading is defining multiple methods with the same name but different parameters in a class.
17. Method Overriding
Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass.
18. Packages in Java
Packages are used to group related classes and interfaces together, preventing naming conflicts.
19. Abstraction
Abstraction hides the implementation details and only exposes the essential features of an object.
20. Abstract Classes
An abstract class is a class that cannot be instantiated and may contain abstract methods, which must be implemented by subclasses.
21. Interfaces
An interface is a contract in Java, defining methods that must be implemented by a class.
22. Static Keyword
The static keyword is used for class-level variables and methods, meaning they belong to the class rather than an instance.
23. Super Keyword
The super keyword refers to the parent class and can be used to access methods and constructors from the superclass.
24. Solved Practice Questions
We'll solve various OOP-related practice problems, applying the above concepts in real-world scenarios.
25. Assignment Solve
Assignments will focus on creating real-life examples using OOP principles, implementing concepts like inheritance, encapsulation, polymorphism, and more.
In this chapter, we explore the backbone of object-oriented programming in Java. Each section will not only introduce key concepts but will be supplemented with clear examples and practice exercises to strengthen your understanding.
Related Posts in My Series:
DSA in Java Series:
Chapter 2: Operators in Java – Learn about the different types of operators in Java, including arithmetic, relational, logical, and assignment operators, along with examples to understand their usage.
Chapter 33: Trie in Java – Explore the implementation and use of Trie data structure in Java, a powerful tool for handling strings, with practical coding examples.
Other Series:
Full Stack Java Development – Master the essentials of Java programming and web development with this series. Topics include object-oriented programming, design patterns, database interaction, and more.
Full Stack JavaScript Development – Become proficient in JavaScript with this series covering everything from front-end to back-end development, including frameworks like React and Node.js.
Connect with Me
Stay updated with my latest posts and projects by following me on social media:
LinkedIn: Connect with me for professional updates and insights.
GitHub: Explore my repositories and contributions to various projects.
LeetCode: Check out my coding practice and challenges.
Your feedback and engagement are invaluable. Feel free to reach out with questions, comments, or suggestions. Happy coding!
Rohit Gawande
Full Stack Java Developer | Blogger | Coding Enthusiast