Java Fundamentals

Introduction to Object-Oriented Programming

Lecture 1

Understanding OOP concepts, classes, objects, and their relationships

Course Goals

By the end of this course, you will be able to:

  • Design Object-Oriented applications using industry-standard patterns
  • Read and create UML diagrams to communicate your designs
  • Implement applications in Java with confidence
  • Apply OOP principles: encapsulation, inheritance, polymorphism
No prior programming experience required! We start from the fundamentals.

Course Structure Overview

Module Topics
1. OOP FoundationsObjects, classes, UML class diagrams, relationships
2. UML BehavioralUse Case, Activity, Sequence diagrams
3. Java BasicsIDE setup, syntax, types, encapsulation
4. Control FlowJVM, conditionals, loops, recursion
5. OOP in JavaInheritance, interfaces, polymorphism
6. Data & CollectionsArrays, collections, exceptions, files

The Problem: Procedural Programming

Before OOP, programs were written as sequences of procedures (functions):

// Procedural approach - data and functions are separate
String[] employeeNames = {"Alice", "Bob", "Charlie"};
double[] employeeSalaries = {50000, 60000, 55000};
String[] employeeDepartments = {"IT", "HR", "IT"};

void giveRaise(int employeeIndex, double amount) {
    employeeSalaries[employeeIndex] += amount;
}

void transferDepartment(int employeeIndex, String newDept) {
    employeeDepartments[employeeIndex] = newDept;
}

// Problems:
// - Data is scattered across multiple arrays
// - Easy to mix up indices
// - Hard to add new employee attributes
// - No way to enforce rules (e.g., salary can't be negative)

Problems with Procedural Code

  • Data and behavior are separated
    • Functions operate on data they don't "own"
  • No encapsulation
    • Anyone can modify any data, leading to bugs
  • Code duplication
    • Similar logic must be rewritten for different data types
  • Hard to maintain
    • Changing data structure requires changes everywhere
  • Doesn't scale
    • Large programs become unmanageable "spaghetti code"

The Solution: Object-Oriented Programming

OOP organizes code around objects that combine data and behavior:

// Object-Oriented approach - data and behavior together
class Employee {
    String name;
    double salary;
    String department;

    void giveRaise(double amount) {
        if (amount > 0) {  // Can enforce rules!
            this.salary += amount;
        }
    }

    void transferTo(String newDepartment) {
        this.department = newDepartment;
    }
}

// Usage is intuitive:
Employee alice = new Employee("Alice", 50000, "IT");
alice.giveRaise(5000);
alice.transferTo("Management");

Benefits of OOP

  • Intuitive - Objects represent real-world things
    • A Car object has properties (color, speed) and behaviors (accelerate, brake)
  • Encapsulation - Data is protected inside objects
    • Objects control how their data is accessed and modified
  • Reusability - Create once, use many times
    • Define an Employee class, create thousands of employees
  • Maintainability - Changes are localized
    • Modify the class in one place, all objects benefit
  • Scalability - Manage complexity through hierarchy
    • Build complex systems from simple, well-defined components

What is an Object?

An object is a thing that has:

  • Identity - What makes it unique (e.g., this specific car)
  • State - Its current properties (color: red, speed: 60 km/h)
  • Behavior - What it can do (accelerate, brake, turn)
Real World: Your car
  • Color: Blue
  • Brand: Toyota
  • Speed: 0 km/h
  • Can: start(), accelerate(), brake()
In Code: Car object
  • color = "blue"
  • brand = "Toyota"
  • speed = 0
  • start(), accelerate(), brake()

Class vs Object: Blueprint vs Instance

  • Class = Blueprint/Template
    • Defines what properties and behaviors objects will have
  • Object = Instance
    • A concrete thing created from the class blueprint
classDiagram
    class Car {
        -String color
        -int speed
        +accelerate()
        +brake()
    }

    class myCar["myCar : Car"] {
        color = "red"
        speed = 60
    }

    class yourCar["yourCar : Car"] {
        color = "blue"
        speed = 0
    }

    class taxiCar["taxiCar : Car"] {
        color = "yellow"
        speed = 45
    }

    Car <|.. myCar : new
    Car <|.. yourCar : new
    Car <|.. taxiCar : new
                

Properties (Attributes/Fields)

Properties describe the state of an object - what it "has" or "is":

  • Properties are nouns: name, age, color, size, balance
  • Each object instance has its own property values
  • Properties define what makes objects of this class unique
classDiagram
    class Dog {
        -String name
        -int age
        -String breed
        -String color
    }
            

Methods (Behaviors/Operations)

Methods define what an object can do - its behaviors:

  • Methods are verbs: run(), bark(), eat(), sleep()
  • Methods can access and modify the object's properties
  • Methods define how other code interacts with the object
classDiagram
    class Dog {
        -String name
        -int age
        -String breed
        +bark()
        +run()
        +eat(food)
        +sleep()
    }
            

The Four Pillars of OOP

Encapsulation

Bundling data and methods together, hiding internal details

"A car hides its engine complexity behind simple pedals"

Inheritance

Creating new classes based on existing ones

"A SportsCar is a Car with extra features"

Polymorphism

Same interface, different implementations

"All vehicles can move(), but each moves differently"

Abstraction

Showing only essential features, hiding complexity

"You use a TV remote without knowing electronics"
We'll explore each pillar in detail throughout this course!

Communicating Design: Why UML?

Before coding, we need to design and communicate our ideas:

  • UML (Unified Modeling Language) is a standard visual language
  • Allows developers to share designs without ambiguity
  • Three essential diagram types:
    • Class Diagrams - Structure of classes and relationships
    • Activity Diagrams - Flow of operations/algorithms
    • Use Case Diagrams - User interactions with the system
Key benefit: Design first, code later. UML helps catch issues before writing code!

UML Class Diagram Basics

A class is represented as a box with three sections:

ClassName
- property1: Type
- property2: Type
+ method1(): ReturnType
+ method2(param): void
  • Top: Class name
  • Middle: Properties (attributes)
  • Bottom: Methods (operations)
  • - means private (hidden)
  • + means public (accessible)

Relationships Between Classes

Objects don't exist in isolation - they interact and relate to each other:

Relationship Meaning Example
Association "uses" or "knows about" Student enrolls in Course
Aggregation "has" (weak ownership) Playlist has Songs
Composition "owns" (strong ownership) House has Rooms
Inheritance "is a" (specialization) Dog is an Animal

Association and Cardinality

An association shows that two classes are connected:

Cardinality indicates how many objects can be involved:

  • 1 - Exactly one
  • 0..1 - Zero or one (optional)
  • * or 0..* - Zero or more
  • 1..* - One or more
  • 1..2 - One to two (as shown: max 2 owners per account)
classDiagram
    class Person {
        -String name
        -String address
    }
    class Account {
        -String accountNumber
        -double balance
    }
    Person "1..2" -- "0..*" Account : owns
            

Aggregation: "HAS-A" (Weak)

Aggregation means one class contains references to others, but they can exist independently:

  • The hollow diamond (◇) indicates aggregation
  • An Email "has" File attachments
  • Files can exist without the Email (shared across emails)
  • Deleting the Email doesn't delete the Files
classDiagram
    class Email {
        -String subject
        -String body
        -Date sentDate
    }
    class File {
        -String filename
        -int size
    }
    Email "1" o-- "0..*" File : attachments
            

Composition: "HAS-A" (Strong)

Composition means strong ownership - the parts cannot exist without the whole:

  • The filled diamond (*--) indicates composition
  • A House "owns" its Rooms
  • Rooms cannot exist without the House
  • Deleting the House deletes all its Rooms
classDiagram
    class House {
        -String address
        -int floors
    }
    class Room {
        -String name
        -double area
    }
    House "1" *-- "1..*" Room : contains
            

Inheritance: "IS-A"

Inheritance creates a hierarchy where specialized classes inherit from general ones:

  • The arrow points from child to parent
  • A Wolf IS-A QuadrupedMammal IS-A Mammal
  • Wolf inherits all properties and methods from its ancestors
  • Wolf can add its own specific properties and methods
classDiagram
    class Mammal {
        -boolean warmBlooded
        +breathe()
        +nurse()
    }
    class QuadrupedMammal {
        -int legCount
        +walk()
    }
    class Wolf {
        -String packName
        +howl()
        +hunt()
    }
    class Dog {
        -String breed
        +bark()
        +fetch()
    }
    Mammal <|-- QuadrupedMammal
    QuadrupedMammal <|-- Wolf
    QuadrupedMammal <|-- Dog
            

Another Inheritance Example: Animal Kingdom

classDiagram
    Animal <|-- Duck
    Animal <|-- Fish
    Animal <|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
      +String beakColor
      +swim()
      +quack()
    }
    class Fish{
      -int sizeInFeet
      -canEat()
    }
    class Zebra{
      +bool is_wild
      +run()
    }
        

Specialization vs Generalization

  • Generalization (bottom → top): Finding common traits
    • "What do Wolf and Dog have in common? They're both QuadrupedMammals!"
  • Specialization (top → bottom): Adding specific traits
    • "A Wolf is a special kind of Mammal that hunts in packs"

When you specialize, the child class:

  • Inherits all properties and methods from the parent
  • Adds its own specific properties and methods
  • Can override inherited methods with specialized behavior

Exercise 1: Identify Objects in a System

Consider a Library Management System:

"A library has books that can be borrowed by members. Each member has a library card. Librarians manage the library and process book loans. Books have titles, authors, and ISBN numbers. Members can reserve books that are currently on loan."

Questions:

  1. What are the main objects (classes) in this system?
  2. What properties would each class have?
  3. What methods (behaviors) would each class have?
  4. What relationships exist between the classes?

Exercise 1: Solution Discussion

Class Properties Methods
Book title, author, ISBN, isAvailable reserve(), checkOut(), return()
Member name, address, cardNumber borrowBook(), returnBook(), reserveBook()
Librarian name, employeeId processLoan(), processReturn(), addBook()
Loan book, member, loanDate, dueDate extend(), calculateFine()

Relationships:

  • Member borrows Book (association, 0..*)
  • Loan links Member and Book (association)
  • Library has Books (composition - books belong to library)

Exercise 2: Bank System Class Diagram

Design a class diagram for a banking system:

  • A bank has customers (identified by name and address)
  • Customers have accounts with a balance
  • Two types of accounts:
    • SavingsAccount - has an interest rate
    • InvestmentAccount - can buy stocks
  • Stocks have a ticker, price, and quantity

Questions:

  1. Draw the classes with their properties and methods
  2. Identify the relationship types (association, aggregation, inheritance)
  3. Add cardinality to each relationship

Exercise 2: Bank System Solution

  • Inheritance: SavingsAccount and InvestmentAccount extend Account
  • Association: Customer has Accounts (1 to many)
  • Aggregation: InvestmentAccount has Stocks (can exist independently)
classDiagram
    class Customer {
        -String name
        -String address
        +openAccount()
    }
    class Account {
        -String accountNumber
        -double balance
        +deposit(amount)
        +withdraw(amount)
    }
    class SavingsAccount {
        -double interestRate
        +calculateInterest()
    }
    class InvestmentAccount {
        +buyStock(stock, qty)
        +sellStock(stock, qty)
    }
    class Stock {
        -String ticker
        -double price
        -int quantity
    }
    Customer "1" -- "0..*" Account
    Account <|-- SavingsAccount
    Account <|-- InvestmentAccount
    InvestmentAccount "1" o-- "0..*" Stock
            

Exercise 3: Model Everyday Objects

For each object, identify properties and behaviors:

Object Properties (State) Methods (Behavior)
Smartphone brand, model, batteryLevel, isOn makeCall(), sendText(), charge()
BankAccount ? ?
Student ? ?
ShoppingCart ? ?
Think: What inheritance hierarchies could you create? (e.g., Student IS-A Person)

Key Takeaways

  • OOP organizes code around objects that combine data (properties) and behavior (methods)
  • Classes are blueprints, objects are instances created from those blueprints
  • Four pillars: Encapsulation, Inheritance, Polymorphism, Abstraction
  • UML helps communicate designs before writing code
  • Key relationships:
    • Association - "uses" / "knows about"
    • Aggregation - "has" (weak ownership)
    • Composition - "owns" (strong ownership)
    • Inheritance - "is a" (specialization)

Next: UML Behavioral Diagrams - Use Case, Activity, and Sequence diagrams to model system behavior.

Slide Overview