Java Fundamentals

Introduction to Object-Oriented Programming

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 diagrams, relationships
2. Java BasicsSyntax, types, IDE setup, compilation
3. Control FlowConditionals, loops, recursion
4. OOP in JavaInheritance, interfaces, polymorphism
5. Data HandlingCollections, files, exceptions
6. Advanced TopicsDesign patterns, functional programming, GUI

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
flowchart LR
    subgraph Blueprint["πŸ“‹ CLASS: Car"]
        direction TB
        Props["String color
        int speed"]
        Methods["accelerate()
        brake()"]
    end

    Blueprint -->|new Car| myCar
    Blueprint -->|new Car| yourCar
    Blueprint -->|new Car| taxiCar

    subgraph Instances["πŸš— OBJECTS (Instances)"]
        myCar["myCar
        ─────────
        color: red
        speed: 60"]
        yourCar["yourCar
        ─────────
        color: blue
        speed: 0"]
        taxiCar["taxiCar
        ─────────
        color: yellow
        speed: 45"]
    end

    style Blueprint fill:#e8f4f8,stroke:#3498db,stroke-width:2px
    style Instances fill:#fef5e7,stroke:#e67e22,stroke-width:2px
    style myCar fill:#fff,stroke:#e74c3c
    style yourCar fill:#fff,stroke:#3498db
    style taxiCar fill:#fff,stroke:#f1c40f
            

Properties (Attributes/Fields)

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

classDiagram
    class Dog {
        -String name
        -int age
        -String breed
        -String color
    }
            
  • 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

Methods (Behaviors/Operations)

Methods define what an object can do - its behaviors:

classDiagram
    class Dog {
        -String name
        -int age
        -String breed
        +bark() void
        +run() void
        +eat(food) void
        +sleep() void
    }
            
  • 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

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:

classDiagram
    direction LR
    class Person {
        -String name
        -String address
    }
    class Account {
        -String accountNumber
        -double balance
    }
    Person "1..2" -- "0..*" Account : owns
            

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)

Aggregation: "HAS-A" (Weak)

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

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

Composition: "HAS-A" (Strong)

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

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

Inheritance: "IS-A"

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

classDiagram
    direction TB
    class Mammal {
        -boolean warmBlooded
        +breathe() void
        +nurse() void
    }
    class QuadrupedMammal {
        -int legCount
        +walk() void
    }
    class Wolf {
        -String packName
        +howl() void
        +hunt() void
    }
    class Dog {
        -String breed
        +bark() void
        +fetch() void
    }
    Mammal <|-- QuadrupedMammal
    QuadrupedMammal <|-- Wolf
    QuadrupedMammal <|-- Dog
            
  • 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

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

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

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)

Our Development Tool: IntelliJ IDEA

We'll use IntelliJ IDEA, a powerful Java IDE:

  • Intelligent code completion - suggests methods and properties as you type
  • Real-time error detection - catches mistakes before you run
  • Powerful debugging - step through code line by line
  • Refactoring tools - safely rename and restructure code
  • UML integration - can generate diagrams from code
Download: IntelliJ IDEA Community Edition (free) at jetbrains.com/idea

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: We'll start coding in Java and bring these concepts to life!

Slide Overview