Object-Oriented Programming Foundations
Introduction to Object-Oriented Design
You are viewing a free preview lesson.
Lesson Overview
Object-Oriented Programming, or OOP, is not simply about creating classes, making fields private, or writing getters and setters.
OOP is an approach to organizing and modeling a program through meaningful objects.
An object generally has:
- State
- Behavior
- Identity
- A clear responsibility
In a small program, it is possible to keep all data and logic inside the main() method.
public class Main {
public static void main(String[] args) {
String learnerName =
"Nur";
int completedLessons =
16;
int totalLessons =
20;
double progress =
completedLessons
* 100.0
/ totalLessons;
System.out.println(
learnerName
+ " completed "
+ progress
+ "% of the course."
);
}
}
This code is simple and readable.
However, as an application grows, we may need to handle:
Learners
Courses
Lessons
Enrollments
Progress
Payments
Assessments
Certificates
If we keep adding more variables and conditions, the code becomes difficult to manage.
OOP helps us organize related state and behavior into meaningful units.
Learning Objectives
After completing this lesson, you will be able to:
- Explain the purpose of OOP
- Understand the conceptual difference between a class and an object
- Identify state, behavior, and identity
- Understand object responsibility
- Understand the difference between procedural and object-oriented thinking
- Identify possible objects from a simple requirement
- Recognize the basic purpose of encapsulation, abstraction, inheritance, and polymorphism
- Avoid common beginner OOP misconceptions
Why Do We Need OOP?
Suppose we are building a learning platform.
A learner has enrolled in a course.
We need to track:
Learner name
Course title
Completed lessons
Total lessons
Enrollment status
For one learner, keeping separate variables is easy:
String learnerName =
"Nur";
String courseTitle =
"Java and OOP Foundation";
int completedLessons =
16;
int totalLessons =
20;
boolean enrollmentActive =
true;
However, with multiple learners and courses, this approach quickly becomes messy.
Example:
String firstLearnerName =
"Nur";
int firstCompletedLessons =
16;
String secondLearnerName =
"Sakib";
int secondCompletedLessons =
18;
As an application grows, problems may include:
- Related values becoming separated
- Updating the wrong learner's data
- Duplicating the same rule in multiple places
- Rewriting the same calculation repeatedly
- Difficulty understanding which code is responsible for which business concept
OOP helps us think in terms of separate concepts:
Learner
Course
Enrollment
Procedural Thinking vs. Object-Oriented Thinking
Procedural thinking usually asks:
What steps need to be executed?
Example:
1. Read completed lessons
2. Read total lessons
3. Calculate progress
4. Print the result
Object-oriented thinking asks:
Which object owns this data, and which object should be responsible for this behavior?
Example:
Enrollment
- Knows completed lessons
- Knows total lessons
- Calculates progress
- Updates progress
Neither approach is always better.
For a small calculation, procedural code may be simpler.
But when related state, rules, and behavior grow, object-oriented organization becomes useful.
What Is an Object?
An object is a specific entity in a program.
Three important characteristics of an object are:
State
Behavior
Identity
State
State is the object's current data.
An enrollment's state might be:
Learner: Nur
Course: Java and OOP Foundation
Completed lessons: 16
Total lessons: 20
Status: Active
State can change.
Before:
Completed lessons: 16
After completing another lesson:
Completed lessons: 17
Behavior
Behavior represents meaningful actions an object can perform.
Possible enrollment behavior:
Complete a lesson
Calculate progress
Cancel enrollment
Check whether the course is completed
In Java, behavior is represented using methods.
Conceptually:
enrollment.completeLesson();
enrollment.calculateProgress();
enrollment.cancel();
Identity
Identity helps distinguish which specific object we are working with.
Two enrollments may have the same state:
Completed lessons: 10
Total lessons: 20
but still be different enrollments.
Example:
Nur → Java
Sakib → Java
Even if both have the same progress, they are not the same enrollment.
This distinction is identity.
What Is a Class?
A class is a custom type that defines the structure and behavior of objects.
Conceptually:
Class:
Enrollment
Objects:
Nur's Java enrollment
Sakib's Java enrollment
Jalisa's Backend enrollment
A class can define:
- What data an object stores
- What behavior is available
- How state can change
A class is not a specific object.
It is the definition for objects of that type.
Class vs. Object
| Class | Object |
|---|---|
| Type or definition | Actual instance |
| Defines state structure | Holds actual state values |
| Defines behavior | Executes behavior |
Course | A specific course object |
Enrollment | A specific enrollment object |
Conceptual Java:
Course javaCourse =
new Course();
Enrollment nurEnrollment =
new Enrollment();
Here:
Course
Enrollment
are classes.
And:
javaCourse
nurEnrollment
are references to objects.
We will study this syntax in detail in the next lesson.
Responsibility
One of the most useful questions in OOP design is:
Which object should be responsible for which task?
Suppose we need to calculate progress.
Possible owners:
Learner
Course
Enrollment
Main
A learner can have different progress in different courses.
Nur
Java → 80%
Backend → 40%
Therefore, progress is not simply learner data.
A course can also have different progress for different learners.
Java
Nur → 80%
Sakib → 90%
Therefore, progress is not simply course data either.
Progress is part of the relationship between:
Learner
+
Course
So Enrollment can be a natural owner of progress.
Conceptually:
enrollment.calculateProgress();
Modeling Simple Concepts
Possible objects in a learning platform might include:
Learner
Course
Lesson
Enrollment
Payment
Each concept can have a different responsibility.
Learner
Possible state:
Name
Email
Account status
Possible behavior:
Update profile
Deactivate account
Course
Possible state:
Title
Price
Publication status
Possible behavior:
Publish
Change price
Enrollment
Possible state:
Learner
Course
Completed lessons
Status
Possible behavior:
Complete lesson
Calculate progress
Cancel enrollment
Keeping State and Behavior Together
Suppose:
int completedLessons =
20;
int totalLessons =
18;
Both values are individually valid int values.
But together, the state is suspicious:
Completed lessons > total lessons
If an object owns this state, its related behavior can enforce the rule whenever the state changes.
Conceptually:
enrollment.completeLesson();
The method can decide whether another lesson is allowed to be completed.
This is stronger design than uncontrolled mutation.
A useful OOP idea is:
The object that owns state can use its behavior to protect the rules of that state.
OOP Is Not Only About Grouping Data
This class groups related data:
public class Enrollment {
String learnerName;
String courseTitle;
int completedLessons;
int totalLessons;
}
That is a useful beginning.
But OOP does not end there.
If any code can write:
enrollment.completedLessons =
-10;
then the object is not protecting its own state.
Later, we will use meaningful methods and controlled access.
Example:
enrollment.completeLesson();
Encapsulation — Preview
The basic idea of encapsulation is:
Keep related state and behavior together, and control how state is accessed or modified.
Example:
course.changePrice(
4990
);
The method can check whether the price is valid.
Encapsulation is not simply:
private fields
+
getter
+
setter
Meaningful behavior and protecting valid state are more important.
We will implement encapsulation in a dedicated lesson.
Abstraction — Preview
Abstraction exposes meaningful operations to the caller while hiding unnecessary internal details.
Example:
course.publish();
The caller only needs to know:
Publish the course
How the internal implementation works is not the caller's concern.
The goal of abstraction is:
Clear intent, fewer unnecessary details.
Inheritance — Preview
Inheritance allows one type to extend the structure or behavior of another type.
Conceptual example:
User
├── Learner
└── Instructor
Inheritance can be useful, but it is not the starting point for learning OOP.
We will study inheritance in detail after classes and objects are clear.
Polymorphism — Preview
Polymorphism allows different implementations of the same common operation.
Conceptually:
EmailNotification
SmsNotification
PushNotification
All of them might support an operation such as:
send();
but each type can behave differently.
We will study this in more detail later.
Four Ideas at a Glance
At this stage, remember only the high-level purpose:
Encapsulation
→ protect state and rules
Abstraction
→ hide unnecessary details
Inheritance
→ inherited relationships between related types
Polymorphism
→ same operation, different implementations
For now, understanding the foundation of classes and objects is more important than memorizing these terms.
A First OOP Preview
The following code is only a preview:
public class Enrollment {
String learnerName;
int completedLessons;
int totalLessons;
void completeLesson() {
if (
completedLessons
>= totalLessons
) {
return;
}
completedLessons++;
}
double calculateProgress() {
if (totalLessons == 0) {
return 0.0;
}
return completedLessons
* 100.0
/ totalLessons;
}
}
Usage:
Enrollment enrollment =
new Enrollment();
enrollment.learnerName =
"Nur";
enrollment.completedLessons =
16;
enrollment.totalLessons =
20;
enrollment.completeLesson();
System.out.println(
enrollment.calculateProgress()
);
Output:
85.0
You do not need to memorize the entire code yet.
For now, observe:
Enrollment object
↓
owns enrollment state
↓
provides enrollment behavior
This Design Is Not Complete Yet
We are still directly writing:
enrollment.completedLessons =
16;
Later, we will see why limiting direct field mutation can be useful.
In upcoming lessons, we will improve this model through:
Classes and objects
Fields and methods
Constructors
Encapsulation
Composition
Immutability
Not Every Problem Needs OOP
A simple calculation:
static int add(
int first,
int second
) {
return first + second;
}
does not need a new class hierarchy.
OOP is more useful when a program contains:
- Related state
- Rules
- Multiple entities
- Changing state
- Relationships
- Meaningful responsibilities
The right tool depends on the problem.
Common Beginner Misconceptions
OOP Means Many Classes
No.
More classes do not automatically create better design.
A class is meaningful when it represents a coherent concept or responsibility.
OOP Means Getters and Setters
No.
setPrice(-500);
If an invalid price is accepted, a mechanical setter does not improve the design.
The goal of encapsulation is to protect state.
Every Noun in a Requirement Must Become a Class
No.
Requirement:
Course title
Here, Course may become a class.
But title may simply be a:
String
field.
OOP Replaces Loops and Conditions
No.
Methods inside objects will still contain:
Variables
Conditions
Loops
Calculations
Algorithms
OOP does not replace fundamental programming logic.
Inheritance Is the Main Goal of OOP
No.
Inheritance is one feature of OOP.
But clear responsibilities, encapsulation, and object relationships are more fundamental.
Identifying Objects from a Requirement
Requirement:
Nur enrolls in a Java course and completes lessons.
Possible concepts:
Learner
Course
Enrollment
Lesson
Step 1: Identify Important Concepts
Ask:
What meaningful things is the program working with?
Possible:
Learner
Course
Enrollment
Step 2: Identify State
Example:
Learner
- name
- email
Course
- title
- lesson count
Enrollment
- learner
- course
- completed lessons
- status
Step 3: Identify Behavior
Course
- publish
Enrollment
- complete lesson
- calculate progress
- cancel
Step 4: Assign Responsibility
Ask:
Who owns this data?
Who should perform this action?
Who should enforce this rule?
Examples:
Course title
→ Course
Learner email
→ Learner
Enrollment progress
→ Enrollment
Step 5: Think About Invalid States
Examples:
Blank course title
Negative price
Completed lessons greater than total lessons
For now, simply identify invalid states.
Later, we will learn how to prevent them using constructors and methods.
Practice Exercise 1: State and Behavior
For the Course concept, write:
- Four pieces of state
- Three possible behaviors
Practice Exercise 2: Choose the Owner
Identify the natural owner of the following data:
Learner email
Course title
Enrollment progress
Lesson duration
Payment status
Choose from:
Learner
Course
Enrollment
Lesson
Payment
Practice Exercise 3: Model an Enrollment
Do not write code.
Conceptually define:
State
Behavior
Possible invalid states
Practice Exercise 4: Procedural or Object-Oriented?
Explain which approach may be simpler for each problem:
- Add two numbers
- Manage course enrollment progress and cancellation
- Convert Celsius to Fahrenheit
- Manage account balance and withdrawal rules
Practice Exercise 5: Responsibility Problem
Consider:
public class Application {
String learnerName;
String courseTitle;
long paymentAmount;
int completedLessons;
void publishCourse() {
}
void processPayment() {
}
void completeLesson() {
}
}
What is the design problem with this class?
Identify possible focused concepts.
Practice Exercise 6: Invalid States
Enrollment state:
completedLessons
totalLessons
active
Identify at least three invalid or suspicious states.
Knowledge Check
Question 1
What is the basic purpose of OOP?
Question 2
What are three important characteristics of an object?
Question 3
What is state?
Question 4
What is behavior?
Question 5
What is identity?
Question 6
What is the difference between a class and an object?
Question 7
What does object responsibility mean?
Question 8
Why might progress be the responsibility of Enrollment?
Question 9
What is the basic purpose of encapsulation?
Question 10
What does abstraction do?
Question 11
What is the basic idea of inheritance?
Question 12
What is the basic idea of polymorphism?
Question 13
Is OOP the best solution for every problem?
Question 14
Why is it useful to identify invalid states early?
Knowledge Check Answers
Answer 1
To organize related state, behavior, and responsibilities into meaningful objects.
Answer 2
State
Behavior
Identity
Answer 3
The current data of an object.
Answer 4
Meaningful actions the object can perform.
Answer 5
The concept that distinguishes which specific object we are working with.
Answer 6
A class is a type or definition. An object is an actual instance of that class.
Answer 7
It describes which object should own particular data, perform particular behavior, and protect particular rules.
Answer 8
Because progress belongs to the relationship between a specific learner and a specific course.
Answer 9
To keep state and related behavior together and control how state is accessed or changed.
Answer 10
It exposes meaningful operations to callers while hiding unnecessary implementation details.
Answer 11
A type can inherit structure or behavior from another related type.
Answer 12
Different types can implement the same common operation differently.
Answer 13
No. A simple calculation or short procedural workflow may often be simpler.
Answer 14
It helps determine which rules constructors and methods should enforce later.
Lesson Summary
In this lesson, we learned:
- OOP is not only class syntax
- OOP is an approach to organizing state, behavior, and responsibilities
- Objects have state, behavior, and identity
- A class is the type or definition of an object
- An object is an actual instance of a class
- Procedural thinking focuses on steps
- Object-oriented thinking focuses on ownership and responsibility
- Keeping related state and behavior in the same object can be useful
- An object can protect the rules of its own state
- Encapsulation helps control state access and modification
- Abstraction hides unnecessary details
- Inheritance can model relationships between related types
- Polymorphism supports different implementations of the same operation
- OOP does not mean creating many classes or writing getters and setters
- Not every noun in a requirement needs to become a class
- OOP does not replace loops, conditions, or algorithms
- Good modeling begins by identifying concepts, state, behavior, responsibility, and invalid states