Object-Oriented Programming (Java)
Class: CSCE-314
Notes:
Introduction
Welcome back, everyone. Up until now, we’ve been thinking about programs in a functional way — focusing on expressions, evaluation, and immutability. We built our solutions by combining functions to transform data.
This week, we start exploring the object-oriented approach — another major programming paradigm that organizes code around objects and their interactions. While functional programming emphasizes what to compute, object-oriented programming (OOP) emphasizes who does the work.
In OOP, we model systems as collections of objects, each representing a thing in the problem domain — a bank account, a car, a student, or even a button in a user interface. Each object encapsulates data (its state) and methods (its behavior).
Some concepts
- Encapsulation:
- Only the people that need, are able to read specific data
- Abstraction:
- A user does not necessarily has to know what the under the hood of an app/function does.
- Removes you a level from detail
- Inheritance:
- In a child-parent relationship, the child has properties/attributes that the parent has.
- Mammals: Parent class
- Dogs: Child class
- Cat: Child class
- Class:
- Gives structure to the data, think of it as a cookie cutter.
- Like the blueprint of a house
- An object is an instance of that class/blueprint
Section 1: The Big Idea - Classes and Objects
Let’s begin by distinguishing two key concepts:
- A class is a blueprint for creating objects. It defines what fields and methods each object will have.
- An object is a specific instance of that class.
Think of a class as a cookie cutter, and each cookie you make from it is an object. The shape and pattern come from the class, but each cookie is its own piece of data.
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
balance = initialBalance;
}
public void deposit(do11uble amount) {
balance += amount;
}
public void withdraw(double amount) {
balance -= amount;
}
public double getBalance() {
return balance;
}
}
Let’s unpack this. public class BankAccount declares a class named BankAccount. private double balance; defines an instance variable. Private means it cannot be directly accessed outside the class, enforcing encapsulation. The constructor initializes the object when it’s created, and the methods define what a bank account can do.
BankAccount myAccount = new BankAccount(100.0);
myAccount.deposit(50.0);
System.out.println(myAccount.getBalance());
When this runs, myAccount is an object, and the methods act as its behaviors.
Section 2: Encapsulation
Encapsulation is one of the core ideas of OOP. It means that the internal state of an object is hidden behind a well-defined interface.
For example, we made balance private — no one outside BankAccount can change it directly. Instead, they must use deposit or withdraw. This keeps the object’s data consistent.
myAccount.balance = -500.0; // ❌ Not allowed
- The compiler would reject this because balance is private. This protection allows us to change the implementation later without breaking the rest of the program.
Instead use:
public void deposit(double amount) {
balance += amount;
}
- Or a setter
Encapsulation helps us think in terms of contracts — what can be done with an object, not how it’s done inside.
Section 3: Classes in the Real World
Let’s take a moment to connect this to real systems.
In a banking application, we might have classes for:
- BankAccount
- Customer
- Transaction
- Bank
Each one has its own fields (state) and methods (behavior). A Customer might have a name, address, and a list of accounts. A Transaction might represent a deposit or withdrawal.
These objects interact with each other through method calls — one object asking another to perform an action.
This interaction forms a network of collaborating objects — much like how, in real life, people and systems work together.
Section 4: Comparing to Functional Thinking
It’s worth pausing to see how this differs from our Haskell mindset.
Functional programming (Haskell) focuses on what to compute, while object-oriented programming (Java) focuses on who performs the action.
| Concept | Functional (Haskell) | Object-Oriented (Java) |
|---|---|---|
| Primary unit | Function | Object |
| State | Immutable | Often mutable |
| Focus | What to compute | Who performs actions |
| Behavior | Defined by functions | Defined by methods |
| Data | Passed into functions | Stored within objects |
In Haskell, we passed data around and let pure functions transform it. In Java, we let objects own their data and decide what actions to perform on themselves. This change in perspective — from functions to objects — is the essence of moving from the functional world to the OOP world.
Wrap-Up
By the end of this week, you should:
- Know how to define a simple class and instantiate objects.
- Understand encapsulation and why we use private fields.
- Recognize how OOP structures programs around objects that know things and do things.
On Wednesday, we’ll do some live coding to create a class together, add methods, and test them interactively in VS Code. Then, on Friday, you’ll work in groups to design your own small domain model — perhaps for a library, zoo, or game.
Recommended Reading
From the open textbook Java, Java, Java: Object-Oriented Problem Solving (Open Textbook Library): https://open.umn.edu/opentextbooks/textbooks/java-java-java-object-oriented-problem-solving
- Chapter 1: Computer Science and Java
- Chapter 2: Objects: Defining, Creating, and Using
- Chapter 3: Methods: Communicating with Objects
- Chapter 4: Input/Output and Encapsulation