Object-Oriented Analysis and Design
This course is about building large software systems through objects. We study how to move from a real-world problem, through a clear statement of what is needed (analysis), to a plan for how to build it (design), and finally to working code. The thread that runs through every stage is the notion of an object — a capsule that holds data and the behavior that acts on that data together. Before we talk about any diagram or model, we need to agree on why we build software this way and what the key terms actually mean. This first session lays that foundation.
This first lecture sets the vocabulary you will use in every later session: object, class, state, behavior, abstraction, encapsulation, inheritance, polymorphism, interface, UML, and design patterns. It also connects those words to the bigger story — that software is built through a lifecycle of analysis and design, and that the reason a whole industry runs on these ideas is that they map directly onto a world we already understand.
Object-Oriented Analysis and Design (OOAD)
| core question: which objects exist, and which is responsible for what?
v
------------------------------------------------
| analysis (WHAT is needed) | design (HOW) |
| problem side | solution side |
------------------------------------------------
| expressed in objects all the way through |
v
implementation (working code)
From the first minute the course establishes a single mental habit that carries through every lecture: speak in objects. When you analyze, you look for objects; when you design, you decide how those objects collaborate; when you code, you implement them. This session gives each of those words a precise meaning, so the rest of the course can assume you already share them.
1.1 The Object-Oriented Paradigm
1.1.1 Object orientation as a design paradigm
Hook — why start at the very beginning? Before you can pick the right diagram or write a single class, you have to answer a deeper question: what is the underlying style in which we build software at all? Every team has to choose a philosophy for how its programs are organized, and that choice quietly shapes every decision that follows.
There are several ways to design and build software, and object orientation is one paradigm — one overall style or philosophy of solving a problem with software. The professor framed it simply: a software design paradigm is just "various ways through which you can build your software." Object orientation sees the world, and therefore the software we build to model it, as a collection of objects that interact.
The core premise is simple to state: our world is made of objects. Look outside a window and you will find ten objects without trying — humans, animals, plants, buildings, cars. Anything we can visualize, any entity with a role to play, is an object. Every object has some properties and some role to play, and the real world runs as a collection of interacting objects each doing its job. A class session, for instance, only happens because students and a teacher are communicating and coordinating with each other through devices such as laptops and phones — many objects, each following some rules, working toward one aim.
This is why object orientation is described as intuitive: because every person can relate to it. When you say "student" or "teacher" or "course," people already share a mental image of the thing, its properties, and what it does. The more a system maps onto things people already understand, the easier it is to design, to explain, and to maintain.
The intuitive label matters beyond comfort. When a system is built from concepts that map directly onto a domain people already know, a new team member can often guess what a class is for and where a feature belongs just by reading the class names — no dense manual required. This mapping is the seed of everything else in the course: analysis, design, and implementation all reuse the same object vocabulary because that vocabulary was borrowed from the real world in the first place.
1.1.2 From functional decomposition to objects
Object orientation did not always exist, and it helps to know what came before it. Historically, computer systems were built with a structured modeling or functional approach: the main building blocks were functions. In languages such as C and C++, a program was essentially a collection of functions, and the data those functions operated on lived separately. The professor pointed out that this mirrors how a real organization looks from the outside: in a retail store there is a manager doing a job, inventory staff working on the back end, delivery people handling dispatch — it all looks like a set of functionalities or behaviors carried out by different people.
The trouble shows up when the world changes. In the functional approach, both the data and the functions that touch it are scattered, so whenever a change is requested, you edit functions here and there, and maintenance becomes very challenging. The idea of object orientation came to prominence around the 1990s (the professor said "during 90s or 95"). Instead of keeping functions and data apart, object orientation joins them: a real-world object's functionality and its attributes (the data, which in programming we call variables or fields) are combined together as one capsule — that capsule is the object. This single shift — data and behavior living together — is the main aspect of object-oriented systems.
The one-line contrast that will recur all course long:
| Structured / functional | Object-oriented | |
|---|---|---|
| Basic building block | Function | Object (a capsule) |
| Data | Lives separately from functions | Lives inside the object (fields/attributes) |
| Behavior | Standalone functions | Methods that live beside the data they use |
| Where change hits | Scattered edits across many functions | Localized — the object owns both |
| Result under change | Hard maintenance | Easier to isolate and maintain |
The single decision to join data and behavior is the entire turnaround: a function that used to reach "outside itself" for its data now sits in the same capsule as that data, so a change to the data's meaning stays close to the code that uses it.
A useful everyday picture. Think of a classic filing cabinet: the tables of data live in one drawer, and the trained people who know how to read and update those tables work elsewhere. When the format of the records changes, you must retrain everyone who touches them, one by one, in many places. Now think of each employee as a capsule that carries both its own records and the procedures for handling them — a change to how one kind of record works is contained to the employee who owns it. That containment is exactly what packaging data and behavior into an object buys.
Q: In older programs we separated functions from data. How is that different now? A: In structured programming, functions and data were separate and lived their own lives. In object orientation they are joined together. State (also called attributes, fields, or properties) and behavior (the functions we now call methods) sit together in one capsule — the object. This exactly mirrors how the real world works, where a thing's properties and what it can do belong to the same thing. Why does this help? Because a real-world object usually changes as one unit — when a car's engine changes, it is the same car that still stops and turns — and modeling that unit directly keeps the software aligned with the world it represents.
1.1.3 The object-oriented programming languages
Because this is an interactive course, the session opened with a quick check of what students already know.
Q: Which object-oriented programming languages do you know? A: Most students said Java. The course follows Java for teaching because the textbook and the design patterns it uses are built around Java (the patterns were originally written in C++), and Java concepts are among the most widely accepted across the world. There is a practical point here: the class does not teach a programming language. If you already know one language, you can learn any other relatively easily, and if you know C++, Java is simple to pick up. So you may implement in any language — but teaching, examples, and the textbook use Java because it keeps the focus on ideas rather than complications.
If you ask us what we do with Java, the answer is that we teach with Java, but we do not teach Java itself. Implementation is part of this course only in the sense that an analysis or design that cannot be implemented is useless. Learning the language itself happens in a dedicated programming course.
Note the distinction the professor was careful to draw: we teach with Java, but we do not teach Java itself. Implementation is part of this course only in the sense that an analysis or design that cannot be implemented is useless. Learning the language itself happens in a dedicated programming course.
// The point here is the shape of a class, not the Java grammar.
// A real design can later be written in Java, C++, Python, or anything else.
public class Book {
private String title; // state lives here
public void print() { // behavior lives here
System.out.println(title);
}
}
The deeper point of this aside is that the language is a vehicle for the ideas. If we had to fight a confusing language, the object concepts would get lost in syntax. Because Java is widely known and its object model matches the textbook, it lets everyone concentrate on deciding what the objects are — the part that generalizes to any language — rather than on the mechanics of a specific one.
1.1.4 Why a common language helps
There is a deeper reason everyone in the course speaks "object," even across roles. Because we find objects in the real world, look for objects during analysis, look for objects during design, and talk about objects during implementation, one particular concept and one vocabulary carries the whole software development lifecycle. When the analysis, the design, and the code all talk about the same objects, communication is much easier, and many mismatches that plague projects are prevented at the source.
Real-world connections and study advice for this section: the languages you will actually meet in industry include Java and C++, and knowing the difference between "teaching with a language" and "teaching a language" will matter when you pick up new tools on a job.
Pitfalls to avoid with this section:
- Treating "object-oriented" as a synonym for "written in Java." Object orientation is a philosophy of organizing design; Java is one language that expresses it. You can write procedural code in Java and you can write object-oriented code in C. Judge the paradigm by how responsibilities are organized, not by the language on the file.
- Confusing "we teach with Java" for "we teach Java." The course assumes you can implement. If you pour effort into Java syntax instead of into deciding what the objects are, you are studying the wrong thing.
- Believing functional programming has no place at all. The point is not that functions are evil — it is that scattering data away from the behavior that uses it makes a large system hard to change. Modern languages blend styles; the course focuses on the object style because that is where its analysis and design skills live.
Recap + bridge. A paradigm is a chosen style of building software. Object orientation chooses to see the world as objects — capsules that join state and behavior — which makes it intuitive and keeps one vocabulary alive from analysis to implementation. That vocabulary is the thread you will pull on for the rest of the course. Next we zoom out from a single object to the whole journey of building software: the lifecycle and the development models that govern how a project actually unfolds.
1.2 The Software Engineering Lifecycle and Development Models
1.2.1 The phases of building software
Hook. Before designing anything, it helps to zoom out and see the whole journey a piece of software takes — from the first request all the way to keeping it alive years later. Why do this now? Because every later diagram and model is a tool that lives inside one of these phases, and knowing where you are in the journey tells you which tool to reach for.
The professor asked the class to recall the software engineering lifecycle — the sequence of phases through which software is delivered to a customer. The agreed list, in a rough order, is:
- Requirements — decide what the system must do
- Design — decide how it will do it
- Implementation — write the code
- Testing — check that it actually works
- Deployment — going live, first to early adopters
- Maintenance — keep it working and improve it over time
The professor added a caution: it is tempting to think of this as a strict sequence, but that is misleading. In practice testing starts early, and pieces of the work overlap, which is exactly why we need development models rather than a rigid checklist.
Why the phases are not a strict line. Imagine you write a whole program and only then begin testing: you would discover design mistakes at the very end, when fixing them is most expensive. In real projects you sketch a design, write a little code, test that piece, get feedback, and refine — activities from several "phases" happening at once in a small cycle. This overlap is the insight that the classic sequential story misses, and it is the reason we talk about models describing how the phases connect.
1.2.2 Development models
A development model captures how you walk through those phases. The session named several:
- Waterfall model — the classic linear model, phase by phase. Each phase finishes completely before the next begins, like water falling level to level. The professor's verdict was blunt: "no one uses" it in practice today.
- Iterative models — these are very popular, because you revisit and improve the system in cycles. You build a small working slice, learn from it, then expand.
- Spiral model — another well-known model that emphasizes repeated risk review rounds. Each loop of the spiral adds functionality while explicitly reviewing the biggest risks before committing more effort.
- Unified Process model — this is the one this course follows, and the textbook is built around it. It works in an iterative fashion, and it is the agile Unified Process (a light, flexible version of the UP) that the companion textbook uses as its running example.
So the takeaway is not that there is one correct sequence, but that there are many software engineering models, and the Unified Process (an iterative model) is the one we adopt for this course.
A useful everyday picture of iterative development. Think of writing an essay by first drafting a rough paragraph, checking it, then expanding paragraph by paragraph — versus writing the whole thing perfectly in one pass. The first approach lets you catch a misunderstood topic early, before the entire essay is built on it. Iterative software development is the same: each small cycle (build a slice, test it, get feedback) exposes mistakes while they are still cheap to fix, instead of discovering one wrong assumption after everything else was built on top of it.
Scope and reach of each model — when each made sense.
- Waterfall assumes you can fully understand and fix the requirements up front, which rarely holds on real projects. It dominates only in simple, well-understood problems (a few hundred lines, a one-page spec) — precisely the small problems where the session later says analysis/design machinery is not even needed.
- Iterative / Unified Process work by acknowledging you cannot know everything in advance: each cycle narrows uncertainty, and requirements evolve alongside design and code (the next phase of this lecture's story).
- Spiral is strongest where risk is the dominant concern (large, novel, safety-critical systems), because its explicit risk-review steps force a "should we keep investing?" decision each loop.
There is no single universally correct model — the choice reflects how well you understand the problem and how expensive failure is.
1.2.3 Why we must analyze and design at all
The professor grounded all of this in history. In the days before the 1970s, programs were written mostly by scientists and mathematicians who fully understood their problems and implemented them directly. Once software became a commercial activity and large teams started building systems, many projects began to fail and there was chaos because people skipped methodology. This led to well-known failure studies, most notably the Standish Report (1995), which tracks how large numbers of software projects fail. The professor asked students to read it (it is also made available on the learning portal) because it is important to understand why projects go wrong.
The dominant cause of failure is instructive: requirements were not understood properly. Teams would develop software, hand it over, and hear "this is not what we asked for." The mismatch happened because either the customer could not state the requirements, or the developers could not collect them, or the two sides simply failed to communicate. The lesson is that modeling and documentation exist to close exactly this gap. There is a balance, though: engineers do not like excessive documentation — "who will read it, it is not a novel or a story." So we produce only the minimum required documentation, but what we do produce must be genuinely useful.
A repeated warning from the session: requirements must be testable and unambiguous. A clear requirement can be checked and agreed on by both sides. If you cannot say exactly what is required, you cannot build a solution — no matter how good a mathematician or programmer you are.
The single root cause of project failure, stated simply. Almost every story of a "successful build, rejected handover" traces back to one fact: the two sides were not talking about the same thing. The customer pictures one product, the developer builds another, and nobody noticed until delivery. Writing requirements down in an unambiguous, testable form and agreeing on them in writing is the cheapest insurance against this — it costs minutes at the start and saves months at the end.
A concrete numbered example of ambiguous vs testable requirements.
Compare these two statements of one requirement for a library system.
- Ambiguous: "The system should be fast." — But what does "fast" mean? A second? A minute? Fast for whom? No one can disagree yet and no one can check it.
- Testable: "The system must return search results within 2 seconds for a catalog of up to 1,000,000 books." — Now both sides can agree, and a tester can run a stopwatch and verify it.
The second form is what analysis aims to produce: a requirement so concrete that a test can prove whether it is met.
Recap + bridge. Software moves through phases (requirements → design → implementation → testing → deployment → maintenance), but the models governing that journey are what matter: waterfall is effectively abandoned, and iterative models such as the Unified Process dominate precisely because they tolerate and exploit the fact that requirements are never fully known up front. History (the Standish Report) shows that misunderstood requirements — not weak programming — are the main cause of failure. That single lesson motivates the very next topic: separating analysis (understanding what) from design (deciding how).
Exam note: know the development models (waterfall, iterative, spiral, Unified Process) and why iterative models like the Unified Process are preferred, since the course and its textbook are built around the Unified Process.
1.3 Analysis versus Design
1.3.1 The simplest way to separate the two
Hook. A project goes wrong in two opposite ways: team designs a solution to the wrong problem, or team perfectly understands the problem but cannot turn that understanding into working software. The oldest, most reliable guard against both is a crisp split between analysis and design — and it can be captured in just two words.
The cleanest mental model given in the session is this: analysis is the problem side; design is the solution side. Two words carry most of the weight:
- What — during analysis you decide what is required.
- How — during design you decide how the system will achieve what is required.
So analysis asks "What does the system do?" and design asks "How do we achieve it?" Investigation is the term closest to analysis: before reaching a conclusion you gather every relevant fact, exactly as a police inspector investigates a case or a doctor investigates a patient's symptoms and possibilities. The professor joked that investigation brings to mind police work, then emphasized the serious message: we should investigate the problem with that same determination to turn over every angle, but using soft skills — being cautious, not treating everyone as a suspect — while still reaching a complete understanding before we conclude.
Formalize the separation with a compact summary. Analysis asks what the system must do and investigates the problem; design asks how the system will do it and specifies the solution. Each term is best qualified: requirements analysis (an investigation of the requirements) and object-oriented analysis (an investigation of the domain objects) are both "analysis"; object-oriented design and database design are both "design." A useful memory device used with this material: do the right thing (analysis) and do the thing right (design).
Q: Isn't analysis just gathering requirements? A: Requirements gathering is part of the story, but not the whole of it. Collecting requirements is what the client-side interaction does — someone talks to the stakeholders and writes down what they want. Analysis goes further: it means understanding the requirements, understanding the problem domain, making the requirements clearer, and writing them down as an unambiguous specification. So the two are hard to separate completely, and we may interact with people again for more understanding, but analysis is the deeper act of understanding what is required, not just the act of collecting a wish list.
Reading the correction as a Q&A. When students described analysis as merely "collecting requirements", the professor pushed back: collecting is only the first movement. The mental model he wanted is that analysis = collection + understanding + clearer + written-down-as-a-testable-spec. If you stop at collection, you have a wish list; if you go all the way, you have a specification that can be checked and agreed upon. The two blend in practice (you may revisit stakeholders), but the direction of the activity is toward understanding, not toward a longer list.
1.3.2 The scope: analysis and design are for big software
Scope — when this machinery is needed and when it is not.
- Analysis and design matter for large software projects — the kind involving hundreds of people and significant cost (the professor gave figures like a team of one hundred people and a budget in the millions of rupees).
- In small programming-course problems — sort an array, build a histogram, a hundred lines of code from a one-page write-up — you simply take the given requirements and implement them; requirement and implementation happen in one step, and none of this machinery is needed.
Why the difference? Once a single person no longer holds the whole picture, you must create a bigger conceptual design before implementation starts, so that many people can cooperate toward one shared understanding. That threshold — one person no longer having the full picture — is exactly where analysis and design begin to pay for themselves.
1.3.3 Requirements and the SRS
Because requirements are the number-one cause of failure, the session spelled out what proper requirements work looks like. We start from an idea or a system and interact with the various stakeholders — the people who have an interest in that software. From customers or clients we collect the requirements, then we convert them into a more formal statement called the Software Requirements Specification (SRS). The SRS is written from the developer's or programmer's perspective, in language developers can act on, and it is signed as an agreement between the customers and the developers. Both sides now share one understanding; the requirements are clear, testable, and unambiguous, and that agreement is the foundation for everything that follows.
The SRS as a signed contract, step by step.
- Gather — interact with stakeholders (customers, clients, and anyone else with an interest) and collect the raw requirements.
- Understand — make sense of each requirement in the context of the problem domain, not just record the words.
- Clarify — resolve ambiguity: turn "fast enough" into a measurable target.
- Write — record the result in a formal Software Requirements Specification (SRS) from the developer's perspective, in language a team can act on.
- Sign — both customers and developers agree to the document, locking a shared understanding.
The signature is the load-bearing step: it converts an informal wish into a mutual, testable commitment that design and implementation can be held against.
1.3.4 Design as a creative, constrained process
Once requirements are clear enough (the professor was quick to note that in software all requirements will not be clear, and that is acceptable), design begins. Design is a creative process: you look at all the alternate solutions and choose the best one, within the constraints you actually face — the resources, the people, the time, and the money available. An engineer has to pick the best solution under those real limits, and that chosen design then has to be implemented by a team of programmers.
The professor offered a memorable analogy: design for software is like architecture for a building. A contractor or architect takes a lot of money to design a building because the design is valuable. A building has many views — front, top, side, left, right, east — and internally it has electrical lines, plumbing, sewage, gas connections, and different kinds of rooms. Similarly, software has a high-level design (like the architectural plan) and a detailed design (like the plumbing, electricity, and rooms — in software terms, the data structures and algorithm design). We create the various modules and packages of the system, and we make them clear to the people who will implement them. The design is expressed as communicating objects and their components.
Extending the architecture analogy. The point is not that a building is pretty — it is that a building is expensive to change after it is built, so the valuable work of thinking through its layout, systems, and constraints happens ahead of time in the drawing. Software is the same: restructuring after the code is written is far more costly than deciding the structure on the plan. The architect analogy also captures the two levels of design — the overall high-level plan (which modules/packages exist and how the big pieces relate) and the detailed design (the data structures and algorithms inside those pieces), exactly like a building's overall form versus its plumbing and wiring.
1.3.5 Why we speak in objects in both phases
A key structural point: we choose to produce the solution in terms of objects because we can relate to objects throughout the entire lifecycle. Whether we are analyzing, designing, or implementing, we talk about the same objects. One vocabulary, consistent end to end. That is the whole aim of object-oriented analysis and design — finding the right set of objects is described as the essence of object orientation, and it is what the rest of the course trains you to do.
Q: How do analysis and design differ for a concrete case? A: Suppose the problem is a library management system. Analysis studies the problem and the requirements: what the system would be, and how it would benefit the user. Design then emphasizes the conceptual solution: creating the schema and analyzing the software objects with respect to it. Analysis pins down what is needed; design decides how the objects and schema will deliver it.
The example below works this out in full.
Worked example: library management system — analysis vs design.
Problem statement: build software that lets patrons borrow and return books, and records who has which book.
Analysis (the problem side — what).
- Identify the stakeholders: patrons, librarians, library administration.
- Ask what the system must do: register patrons, search the catalog, check out a book, return a book, record the borrower.
- Clarify and specify testable requirements, e.g. "search must return matching titles within 2 seconds for up to 1,000,000 catalog records."
- Write and agree the SRS.
Design (the solution side — how).
- Decide the conceptual structure: a database schema (tables for
Patron,Book,Loan) and the software objects that work with it. - Decide which objects exist and what each is responsible for: a
Patronobject knows a patron's ID and borrowed items; aLoanobject records who borrowed which book and when. - Choose how those objects collaborate to carry out each use case (borrow, return, search).
The same "library" idea appears on both sides, but analysis described what the system offers while design specified which objects and schema deliver it. This is exactly the What/How split in a concrete case.
An intuition worth keeping: analysis is about the problem, design is about the solution, and neither is a pure stage — they blend into each other, but keeping the What/How distinction in mind prevents the two most common errors (designing before understanding, or collecting wishes without specifying a testable need).
Recap + bridge. Analysis is the problem side (what), design is the solution side (how); requirements get pinned down into a testable, signed SRS, and design is a creative but constrained choice of conceptual solution expressed in objects. In real big projects these blend, but keeping the split straight prevents the two classic failures. Next we leave the process and start naming the building blocks themselves: what exactly an object, a class, state, and behavior are — the vocabulary every design decision depends on.
Exam note: be ready to apply the What/How split (analysis = problem side = what; design = solution side = how) to a concrete case such as the library management system.
1.4 Objects, Classes, State, and Behavior
1.4.1 Real-world objects
Hook. The word "object" gets thrown around constantly, so it is worth pinning down with a working definition that will do all the heavy lifting for the rest of the course: an object is anything that carries state and exhibits behavior. Almost every later rule about analysis and design is an application of this one sentence.
We return to the starting intuition and make it precise. In the real world, an object is anything that has state and exhibits behavior:
- State means the properties, attributes, or fields — for a student, the name, ID number, date of birth, marks. In older languages these were the variables holding information.
- Behavior means the functionality, the responsibilities, the roles — what the object does. In programming terms these are the functions, which in object orientation we call methods.
Everywhere around us, objects combine these two: a dog, a car, a bicycle, a fan, a room, an air conditioner, a pen. The professor's phrase is that each object has "some state information, some behavior," and a role to play. When we build software, we capture only some of that — and that act of choosing what to keep is called abstraction, which we meet properly in the next section.
Two defining halves, stated side by side.
| Half | Real-world meaning | Programming term(s) | Example (student) |
|---|---|---|---|
| State | The properties that describe the thing | attributes / fields / variables | name, ID, date of birth, marks |
| Behavior | What the thing can do | methods / functionality / responsibilities / roles | register, attend, submit |
The essential move: state and behavior belong to the same object. That was the paradigm shift we met in Section 1.1, and now we finally name the two halves.
1.4.2 Classes are templates for objects
An object is a concrete instance. A class is the template, prototype, or blueprint that describes a whole kind of object: what common properties and what responsibilities each individual of that kind will have. The professor emphasized repeatedly:
Q: What is the difference between a class and an object? A: A class is a template or blueprint that lists the common properties and responsibilities of a whole kind of thing. An object is one concrete instance of that class. You yourself are an object of the class "student"; a particular car you own is an instance of the class "car."
Formalize with the standard analogy: the blueprint versus the built thing.
A class is the blueprint — a description of what a kind of object looks like and can do, filled in with blanks. An object is one concrete realization of that blueprint, with every blank actually filled in:
- Define "Student" once → get Ankit, Sowmya, Raghav as separate objects.
- Define "Building" once → get all the separate buildings in an organization.
- Define "University" once → every individual university is an object.
A single blueprint can stamp out any number of distinct instances, each with its own values for the same set of attributes.
The professor gave a powerful framing worth keeping: classes are user-defined data types. A predefined type like int describes a set of allowed values and the operations you can perform on them; each int variable you declare is one instance. A class is exactly analogous: you define the type (the class), compile it, and later create any number of objects from it — each object being one instance of your user-defined type.
1.4.3 Class notation and the book example
It is worth seeing how a class is drawn and used, because this notation returns throughout the course. A class is shown as a rectangle divided into three parts: the class name at the top, the attributes in the middle, and the methods at the bottom. The professor's running example was a book:
- Class name:
Book - Attribute:
title(and we can add more, such as the number of pages, or the author name) - Method:
print— a method that prints the title
+------------------+
| Book | <- class name
+------------------+
| - title | <- attributes (the state)
+------------------+
| + print() | <- methods (the behavior)
+------------------+
Once the Book class is defined, we can create any number of book objects, one per different subject or title, and each can run print to show its title. When we finally implement, this small diagram becomes a plain class with a method and an attribute — public class, a title field, and a print method. This tiny example captures the whole pipeline: we look at the real world, we analyze the concepts, we create a design, and then we implement.
Read the three-compartment rectangle correctly. The top shows the class's identity (its name), the middle lists its state (attributes, what it remembers), and the bottom lists its behavior (methods, what it can do). In UML, the marker in front of a member tells its visibility: + means public, - means private, # means protected — a detail that matters fully once we reach encapsulation in Section 1.5.
The professor noted an important philosophical detail about responsibility. In the real world a book does not print itself — somebody else prints it. But in software we often give one object the whole responsibility it can carry, because the object holds all the information it needs. For example, an employee software object can be given the method to generate its own salary once thirty days have passed; the real-world employee would never cheat, so we can trust the computed object to produce the value fairly. Likewise a book object, looking at itself, knows its title and author, so we write a method that lets it report them. This is an actualization of reality — modeling the real world into software objects that can answer for their own data.
Scope — where the "object does its own work" idea applies. This responsibility assignment is a design choice, not a law of nature. A book in the real world does not print itself; we choose to give a software Book object a print method because it holds its own title. The same principle drives the salary example: the employee object holds the data it needs to compute its own salary, so it can carry that responsibility safely. This foreshadows a central course skill — assigning responsibilities to objects (the "responsibility-driven design" idea) — but note the assumption that makes it safe: the object must genuinely hold all the information needed to discharge the responsibility fairly and correctly.
The professor's library case study (already present in the course material) will be a recurring example: in the real library you have books, a librarian, and a library building; in the software we search for the corresponding objects that issue a book, return a book, and record a borrower's details. What used to be done with paper catalogs and library cards is done today entirely by software.
1.4.4 Worked example: the course object
To make state and behavior concrete, the class considered a course — which is a concept, not a physical thing, and therefore a great test of the idea. You have never seen a course; you have seen its printout, its handout, its schedule. The professor asked: what are the state and behavior of a course object?
Worked example: identifying the state and behavior of a course.
A course is a concept, not a physical object, so it is a hard but revealing test of the idea.
State (attributes) — what a course remembers:
- course number (e.g.
OODAP101) - course handout
- the number of units (credits) it carries (e.g. 4)
- the instructor (e.g. "Professor X")
Behavior (methods) — what a course must be able to support:
- allow students to register and enroll
- allow students to attend classes
- support the conduct of delivery and evaluation
Sense-check: this matches how a real course works — a course has identity (number), descriptive data (handout, credits, instructor), and roles (enroll, attend, deliver, evaluate). Even though we can never point at "a course" the way we point at a dog, it still cleanly separates into state and behavior.
This example teaches two things. First, concepts (bookings, transactions, a course) can be objects even though they are not physical — a banking transaction or a railway reservation is a concept, not a tangible thing. Second, identifying state is usually easy, while identifying the methods is the difficult part — you have to decide what roles the object must actually play in your system.
Recap + bridge. An object = state + behavior; a class is the blueprint/template from which many objects are stamped, and classes are user-defined data types. The class rectangle (name / attributes / methods) is the notation you will see everywhere. We also met the recurring insight that choosing methods is the hard part. But notice: to define state we had to decide what to keep — a book has many features we did not model. That act of choosing is called abstraction, and together with encapsulation it is the subject of Section 1.5.
1.4.5 The integer range aside
The professor mentioned, in passing, that predefined types like int come with a built-in domain of allowed values. The exact figures spoken aloud were garbled, but the idea is standard and worth recording with that caveat:
Reconciling the integer range. The spoken phrase ("2 to the power minus 2 to the power 32 …") was garbled; the standard signed 32-bit int range in two's-complement is indeed
which numerically is from -2,147,483,648 to +2,147,483,647. (A signed 32-bit type dedicates one bit to the sign, leaving 31 bits of magnitude, hence on each side — the larger magnitude is on the negative side because two's complement has no separate "negative zero" value to waste a slot on.) The spoken "32" was a slip; the correct bound is . The point being made is simply that a type declares a range of values plus a set of operations (addition, multiplication, division), just as a class declares attributes plus methods.
Pitfalls to avoid with this section:
- Conflating class and object. The class is the blueprint; the object is the built instance. "Student" is a class; "Ankit" is an object. Mixing them up causes errors every time you try to attach a specific value to a generic definition.
- Modeling too much state. A real book has hundreds of features (weight, smell, cover material). Software models only the ones the problem needs — deciding which is abstraction. The hardest, most valuable skill is often choosing what to leave out, not what to include.
- Under-investing in methods. Because state is easy to list, beginners instinctively start there and forget the behavior. The professor flagged this repeatedly: identifying the methods is the difficult part.
- Forgetting that concepts can be objects. A course, a transaction, a reservation are objects even though you cannot touch them. Restricting "object" to tangible things is a common mental mistake.
Real-world domain connection. This is the mental machinery behind everyday software: a banking "transaction" is a non-physical object with state (amount, date, accounts) and behavior (debit, credit, rollback); a railway or flight "reservation" is an object with state (seat, passenger, flight) and behavior (book, cancel). When employees build these systems, they are really deciding the state and behavior of a set of software objects — exactly the task worked here for the course.
1.5 Abstraction and Encapsulation
1.5.1 Abstraction
Hook. We said a software object captures "only some" of a real-world object's features — but which ones, and how do we choose? That choosing is not an afterthought; it is a named, fundamental idea called abstraction, and it is the first of the two pillars (abstraction + encapsulation) that keep object-oriented systems manageable.
Abstraction is the act of ignoring what is not needed. When we model a real-world object as a software object, we do not — and cannot — copy every feature. We keep only the properties and behaviors that are relevant to the particular problem, and we deliberately ignore the features that are not relevant. The professor's example: as a teacher in this class, he is not interested in what students earn, or what they do in the evening, or what other courses they take, so those features are abstracted away. What matters is that you are a qualified student of the institution, so those features stay. Abstraction is how we organize the world and reduce its complexity; "through abstraction we achieve encapsulation," and it is how we decide what each software object must contain.
Formalize abstraction with a three-step recipe.
- Identify the real-world thing you are modeling.
- Select the features that matter for your particular problem.
- Ignore everything else — deliberately and consciously.
The selector is the problem itself. A Student object in a library system cares about name and ID (to check out books) but not about marks or evening plans. The same real student modeled for a university records system cares about exactly those marks. The object is defined by the problem you are solving, not by a complete copy of the person.
A fresh everyday analogy — the street map. A street map of a city deliberately leaves out trees, streetlight colors, and the exact width of lanes; it keeps only what a driver needs (roads, names, turn directions). No one calls the map "wrong" for omitting the trees — the omission is exactly what makes the map useful. Abstraction is the same: a software object is a map of a real thing, and its value comes from what it deliberately leaves out as much as from what it includes. The analogy breaks in one place: a map is drawn once, whereas an object must also behave within a running system — so abstraction decides both what to store (state) and what to do (behavior).
1.5.2 Encapsulation
Encapsulation is the packaging of those chosen attributes and methods into a module, together with controlled access. The professor described it in terms of security and structure: "I need to safeguard my code. Anyone should not be able to change it, and I need to provide a structure to it."
Formalize encapsulation as two joined ideas. Encapsulation = bundling (put the chosen state and behavior together in one module) + controlled access (decide who may touch each part of it). Bundling is what we already described in Section 1.4; the new ingredient is the second half — the gates that control who gets in, which is where the access keywords come in.
The mechanical tools for this are access keywords:
- public — visible and usable by anyone.
- private — visible only inside the object; the outside world cannot touch it.
- protected — a third level, which becomes relevant once we talk about inheritance.
A real-world picture of encapsulation: an institution's online learning portal is not open to everyone. Only people who are actually enrolled at the institution get a login and ID; some things are private, some are public, some are protected. By marking members public, private, or protected we get to encapsulate our objects — we let outsiders use an object only through the safe interface we choose to expose, while the private inner workings stay hidden and unchangeable from the outside.
The professor linked this to information hiding: "if I have all the information, I only have the capabilities to generate it; I don't want to expose myself; I want to safeguard my information as private." In a system, you give access to whatever information somebody is supposed to have — and nothing more.
A concrete picture — the bank account. A bank account object holds its balance as a private field. Outsiders cannot directly set the balance to whatever they like; instead the object exposes controlled public methods like deposit(amount) and withdraw(amount). The data is protected, and every change to it flows through a gate that can enforce rules (e.g. you cannot withdraw more than you hold). That is encapsulation in action: private state plus controlled public behavior, with the private internals hidden from outside code.
Pitfalls to avoid with this section:
- Treating abstraction as "leaving out anything." The ignored features must be irrelevant to the current problem, not merely inconvenient. Omitting something the system genuinely needs creates a broken model, not a simpler one.
- Making everything public "to keep it simple." If every field is public, outsiders can corrupt the object's state directly and bypass its rules — the portal becomes open to everyone. Guarding by default and exposing only what is needed is the safer habit.
- Equating encapsulation with privacy only. Privacy is the tool; the goal is bundling the state with the behavior that manages it, then controlling access. A private field with no behavior to change it is useless, just as a public free-for-all is unsafe.
- Forgetting the hard part is methods. In both Section 1.4 and here the professor warns: attributes are easy to list; deciding the responsible behavior is the difficult, valuable skill.
A teaching warning that came up here: the difficult part of building a class is identifying methods, not attributes. Attributes (the state, the fields) are comparatively easy to list; deciding what behavior the object must responsibly perform is the harder, more valuable skill.
Recap + bridge. Abstraction selects what a software object keeps (the relevant features) and encapsulation packages that selection together with controlled access via public/private/protected. Together they reduce a messy world to a clean, guarded capsule. Abstraction and encapsulation gave us a single object; the next idea is about relating many objects to one another. Inheritance lets new classes reuse and extend what already exists — the topic of Section 1.6.
Real-world domain connection. Abstraction and encapsulation are why modern systems stay maintainable at scale. A banking core, an airline reservation engine, or an e-commerce checkout is a landscape of objects whose internals are hidden behind public interfaces; a team can change a private implementation (say, a new way to store a balance) without breaking the thousands of callers who only use the public deposit/withdraw methods. The street-map and portal pictures above are not just classroom doodles — they are how real large systems are kept safe to change.
1.6 Inheritance
1.6.1 Generalization and specialization
Hook. Every object we built so far was created from a blueprint with no relationship to other blueprints. But real things are rarely disconnected — a car is a kind of vehicle, a dog is a kind of animal, a surgeon is a kind of doctor. This "is-a-kind-of" relationship is the seed of inheritance, one of the most heavily used ideas in the whole course.
Inheritance is the concept of defining a new class by reusing what already exists in a parent class, and it mirrors the real world's parent–child relationship. We inherit many features, properties, and ways of doing things from our parents. In software, inheritance is a way to avoid rewriting code again and again — a major source of reuse.
The professor framed inheritance as generalization and specialization:
The two directions of inheritance, exactly stated.
- Generalization is the broader category. Every doctor first does the general medical training (MBBS);
Vehicleis a generalization ofCar,Truck, andBus. - Specialization is the narrower refinement. After the general training, a doctor specializes in surgery of the eyes, the stomach, or the brain;
Car,Truck, andBusare specializations ofVehicle.
A general class holds what all the special cases share (a Vehicle has wheels and a top speed); each specialized subclass inherits that common content and adds only what is unique (a Truck adds cargo capacity; a Bus adds passenger seats). This is exactly the doctor model: first the common foundation (MBBS), then the unique refinement (which organ to operate on).
The whole world is organized hierarchically: there is a plant hierarchy and an animal hierarchy; companies are hierarchies (CEO, directors, presidents, others); families have a family tree. Inheritance is naturally drawn as a tree structure, and it is precisely because the world is hierarchical that inheritance is such a natural and "very popular, simple" tool.
Visualize the tree. Draw Vehicle at the top; beneath it branch Car, Truck, Bus. Each child points up to its parent. The shared facts (wheels, speed, an engine) live once at the top and flow down to every child; the unique facts live at each child. Roots at the top, branches below — exactly a family tree, which is how worlds are organized and how inheritance is drawn.
1.6.2 Reuse is the goal
The underlying goal of object orientation in software is reuse of what you already know. Every time you use int or float, you are reusing a predefined type that someone built for you. With user-defined items, at design-pattern level as well, you do not want to construct everything from scratch — you inherit from the relevant class and add only what is new. This is the same philosophy behind design patterns (Section 1.10): reuse proven solutions rather than reinventing them.
Formalize the payoff of inheritance: write once, use many times. Without inheritance, a Car, Truck, and Bus class would each re-print the code for wheels, engine, and speed. With inheritance, that common code is written once in Vehicle and each subclass inherits it automatically, adding only its own few lines. The bigger the shared base, the more duplication is removed — which is why reuse is described as a major source of software economy.
Vehicle (wheels, topSpeed — written once)
/ | \
Car Truck Bus (each adds only its unique parts)
The professor drew a deliberate parallel to keep in mind: inheritance and polymorphism are closely related — polymorphism is the mechanism through which inheritance is usually realized, and the two concepts tend to appear together.
A real-world anchor: because reuse is the core of object orientation, "every software need not be designed from scratch" — an idea that also underlies design patterns and the way real companies build libraries of reusable components.
Pitfalls and scope to avoid with this section:
- Inheriting for the wrong reason. Use inheritance only when there is a genuine is-a relationship ("a Truck is a Vehicle"). Inheriting just to borrow a few methods, when the two classes are really unrelated, couples them artificially and makes future change painful.
- Forgetting that inheritance is one-directional. A subclass inherits from its parent, not the other way around; general classes know nothing about their specific children. "Vehicle" does not depend on "Bus".
- Assuming inheritance is the only reuse tool. The professor links inheritance to polymorphism and design patterns — reuse also happens through composition and patterns. Inheritance is a major source of reuse, not the exclusive one.
- Confusing generalization with specialization direction. Generalization moves toward the broader category; specialization moves toward the narrower one.
Vehicle⭢Caris specialization;Car⭢Vehicleis generalization.
Recap + bridge. Inheritance defines a new class by reusing a parent's content, framed as generalization (broader) and specialization (narrower), drawn as a tree, and aimed at reuse. Because reuse and the "is-a" relation power it, inheritance almost always appears together with its partner concept — polymorphism, Section 1.7, which is the mechanism that lets one interface behave differently across inherited classes.
Real-world domain connection. Inheritance is everywhere in real code bases and industry libraries. A framework's base Component class is generalized into Button, TextField, and Checkbox subclasses that inherit common behavior and add their own; an e-commerce catalog builds Product once and specializes into PhysicalProduct and DigitalProduct. Because companies reuse hardened, tested base classes instead of rewriting, their libraries grow more reliable and cheaper to maintain over time.
1.7 Polymorphism
1.7.1 One interface, many implementations
Hook. Inheritance let us reuse a parent's content, but it does not yet explain a subtler power: how can code call the same operation and get the right behavior for whatever specific object it happens to be holding? The answer is polymorphism — literally "many forms."
Polymorphism ("many forms") was defined in the simplest sticky way: one interface, multiple implementations. The same public interface can be backed by different internal implementations, and the caller does not care which one it gets.
Formalize the three words that make up the definition.
- one interface — a single, agreed public way in (a set of operations, e.g.
print(), or a connector shape). - multiple implementations — many different internal ways to carry out that interface (each device does it differently).
- the caller does not care — the code that uses the interface never needs to know which implementation it is talking to.
This is what "many forms" means: one shape on the outside (the interface) with many actual bodies behind it.
The professor's favorite example was the USB connector. USB is one interface through which you can plug in a mouse, a keyboard, a pen drive — many different devices, each with its own implementation, all connecting through the same interface. Extending the idea to cars: Maruti, Hyundai, BMW, and Tesla all make cars with their own implementations, but the interface of driving — the steering wheel, the accelerator, the brake, the clutch — is the same. You learn one interface and can drive all of them.
Restating the professor's USB analogy in words, and where it fits. One USB socket (interface), many devices (implementations): your laptop does not care whether you plugged in a mouse or a pen drive, because both fulfill the same "connect and work" contract. Cars are the same picture at a larger scale — the pedals and wheel are one interface; every manufacturer's internal car is a different implementation, yet the same interface drives them all. The analogy is exact: in both, the cost of learning is paid once, because the interface stays fixed while the implementation changes freely behind it.
Each object exposes its own public interface through which people interact, and behind that interface there can be multiple implementations. The professor tied this back to the earlier point: polymorphism is the aspect through which inheritance is often achieved, so the two are very closely related.
How inheritance and polymorphism connect. Inheritance sets up a family of classes (a Vehicle and its subclasses); polymorphism lets a caller treat any of them through the same interface. Concretely, code holding a Vehicle reference can call its start() method, and whether the actual object is a Car, Truck, or Bus determines which start() runs — one interface, many implementations, realized through the inherited family. Inheritance supplies the family; polymorphism supplies the flexible dispatch through it.
1.7.2 Why polymorphism matters for design
Because every object has interfaces and the implementations behind them are free to differ, designers can swap implementations without disturbing the users of the interface — the system becomes flexible and open to change. That flexibility is exactly what makes object-oriented systems easier to maintain than the older function-based designs, which is a thread running through the whole course.
A fresh everyday analogy — universal power socket. A wall socket is one interface; the appliance plugged into it is an implementation. You can unplug a lamp and plug in a phone charger without rewiring the wall — the caller (the wall) never changes even though the implementation (the appliance) is completely different. Polymorphism gives software the same property: a caller written against an interface keeps working even when the object behind it is swapped for a new class.
Pitfalls and scope to avoid with this section:
- Conflating polymorphism with inheritance. They are partners, not the same thing. Inheritance is the family structure; polymorphism is the behaviour of calling one interface that many implementations fulfill. You can have polymorphism without direct inheritance (e.g. separate classes implementing the same interface).
- Confusing "interface" here with the Java keyword only. Polymorphism's "one interface" is the conceptual public contract — the USB socket or the driving pedals. Java's
interfaceconstruct is one concrete way to express it (Section 1.8), but the idea is broader. - Forgetting the caller's viewpoint. Polymorphism is only useful if the caller treats everything through the interface. If callers constantly check "what type is this?" and branch, you have lost the benefit and re-coupled the code.
Recap + bridge. Polymorphism = one interface, many implementations: the caller does not care which implementation lies behind the interface it uses, which is what makes systems flexible and open to change. It is the realization mechanism for inheritance and a thread the whole course pulls on. The word "interface" keeps appearing — next, Section 1.8 makes that concept precise: what an interface is as a black-box contract, and how it separates stable usage from changeable internals.
Real-world domain connection. Polymorphism underlies much of how real software stays open to change. A graphics library draws Circle, Square, and Triangle through one draw() interface — new shapes join without changing the software that renders a list. Plug-in systems, hardware drivers, and the USB/car examples are all the same pattern: a fixed public interface, swappable implementations, and callers that stay unchanged.
1.8 Interfaces
1.8.1 The bridge of interfaces
Hook. Polymorphism said callers use "one interface" — but what exactly is an interface? It turns out the word does double duty in this course: it is a deep conceptual picture (the black box) and a concrete Java construct. Understanding both keeps the two meanings from tangling, and this section separates them.
An interface is the contract between a class and its users. When you create an object, the people using it need to know how they may use it, and you provide a public interface that says: this is the way you can use me. The professor's picture is the black box: the user knows what the object does and how to invoke it, but not how it does it.
Formalize the interface as a black-box contract. An interface guarantees what operations exist and how to call them (their signatures) — but says nothing about how they are implemented. The user reads the interface, invokes the operations, and never steps inside the box. The guarantee it makes is a two-way agreement: I promise to behave this way; you promise to use me only this way. Because the user needs to understand only the interface, the enormous complexity of the implementation is hidden and safe.
Every individual and every product has some interface. A projector or a laptop exposes a USB port — an interface that lets other things connect and use the device's services. Every organization has a public interface; every product has a user interface through which users interact. When you declare an interface, you guarantee a particular behavior: through this interface is a contract between user and class — this is the way I will behave. The user needs to understand the interface but does not need to enter the implementation.
1.8.2 Interface versus implementation
A crucial separation the session emphasized is between the interface of a class and its implementation:
- Interface — the agreed, stable way to use the object. You design it carefully so it does not need to change.
- Implementation — the internal details, which will keep changing as new algorithms, new requirements, and improvements come along.
Because these are separated, you can change the implementation any time while it stays hidden from the end user; the visible functionality you do not want to change is locked in the interface. This is the practical payoff of encapsulation and abstraction — the world's complexity is reduced by restricting how much of each system you must understand to use it safely.
A compact before/after table of the separation.
| Aspect | Interface | Implementation |
|---|---|---|
| What it is | Agreed, stable way to use the object | Internal details of how it works |
| How it changes | Designed to stay fixed | Keeps changing (algorithms, requirements, improvements) |
| Who sees it | The user/caller | Hidden from the user |
| Role | Locks the visible behavior | Carries the changeable internals |
The two are deliberately separated so you can improve the hidden internals freely without ever breaking the fixed contract the users rely on.
1.8.3 Interfaces and Java
An important, exam-relevant technical point: in Java, interfaces are also how multiple inheritance is implemented. A class can inherit behavior from multiple interfaces (while normal class inheritance is single). So the word "interface" does double duty in the course — it is the conceptual black-box contract and a concrete Java construct that enables multiple inheritance. This is worth flagging because the two meanings are easy to conflate.
How the two meanings of "interface" differ (and why it matters).
- Conceptual meaning (the broad idea, Section 1.8.1): a black-box contract between a class and its users, the stable way in. This applies to any object-oriented design.
- Java meaning (Section 1.8.3): a concrete Java construct
interfaceused to declare a contract that classesimplement, and the mechanism through which a class gets multiple inheritance of behavior (a class can implement several interfaces, while a Java class can extend only one superclass).
Conflating the two is a classic slip. The conceptual interface is the general idea; the Java interface is one language's way of expressing both that contract and multiple inheritance. Both reduce to the same shared mental model the professor gave: one interface, many implementations — exactly polymorphism, whether the interface is a USB port, a car's pedals, or a Java interface.
// Java: one interface, many implementations (and multiple inheritance of behavior).
public interface Connectable {
void connect();
}
public interface Chargeable {
void charge();
}
// A class may implement SEVERAL interfaces -> multiple inheritance of behavior.
public class USBDevice implements Connectable, Chargeable {
public void connect() { /* USB-specific */ }
public void charge() { /* USB-specific */ }
}
Recap + bridge. An interface is a black-box contract separating the stable, agreed way to use an object from its changeable, hidden implementation — the practical payoff of abstraction and encapsulation. In Java the same word also names a construct for multiple inheritance of behavior. That closes the core building blocks: object, class, state/behavior, abstraction, encapsulation, inheritance, polymorphism, interface. The remaining big idea before the course's method becomes clear is the shared language used to draw all of it — UML and use case analysis, Section 1.9.
Real-world domain connection. The interface/implementation split is what lets a whole industry upgrade internals without breaking users. A bank changes how it stores balances (implementation) while its account API (interface) stays identical; a phone vendor changes the chips inside the same USB-compatible port. Behind every stable API, library, or network protocol, this same separation lets the changeable world keep working for everyone holding the fixed contract.
1.9 UML and Use Case Analysis
1.9.1 UML as a common design language
Hook. We now have a precise vocabulary of object concepts — but ideas still need a way to be written down and shared across a team, or the vocabulary is useless. That shared written language is UML, the Unified Modeling Language, and this section explains why a standard notation is so valuable.
UML, the Unified Modeling Language, is the notation this course uses to communicate models. It came about because earlier each modeling school had its own terms and concepts, and UML unified them all into one design language. When we draw analysis models and requirements, or design models, UML is the shared vocabulary with which we express them.
Why a unified notation matters. Before UML, different methods (Booch, OMT, Objectory) each had their own shapes and rules, so a diagram drawn by one team was confusing to another. UML merged those methods into a single standard notation, so the same class-rectangle, the same lines for inheritance, the same shapes are used everywhere. A common language means a developer from any background can read a model without retraining — exactly the same benefit the course's "one object vocabulary" gives from analysis through implementation. On this course, that shared drawing language is how models are communicated.
There is a strong practical reason to draw models rather than only write text: clients and stakeholders are not interested in reading long text documents. They understand pictures and graphical models far more easily. So much of the modeling in this course is visual — diagrams people can look at and nod along with.
A useful everyday picture — the floor plan, not the manual. You could describe an office building in thousands of words, but an architect's floor plan shows the layout in seconds and lets everyone (owner, builder, electrician) share the same picture. UML diagrams play this role for software: a class diagram or use case diagram is a picture both technical and non-technical people can grasp quickly. The analogy breaks in depth — a floor plan shows static layout, whereas UML includes dynamic diagrams too (interaction, state) — but the core point, pictures communicate faster than prose to everyone, is exactly why modeling is visual.
1.9.2 Use case analysis
Because requirements are the number-one cause of project failure, the course puts heavy weight on gathering them well, and the tool we use for that is use case analysis. To collect requirements we must satisfy and interact with the end users. This is why the approach is called use case analysis: we describe the system through the cases in which users actually use it. The professor noted a curiosity: strictly speaking, use case analysis itself has no object orientation — yet it has become the de facto standard for analyzing a system, and it is a main component of the course, combined with object-oriented analysis.
Formalize what a use case is. A use case is a story or scenario of how a person (an actor, typically an end user) uses the system to reach a goal. Instead of describing the system abstractly, you describe the concrete cases of use:
- Actor: the end user (e.g. "Patron").
- Goal: what they want to achieve (e.g. "borrow a book").
- Scenario: the sequence of steps (e.g. patron searches catalog, selects a book, checks it out; the system records the borrower and loans it).
A use case is written as a readable story, not as objects or a diagram first. The professor's point of caution is real: use cases are not, by themselves, an object-oriented artifact — they are written stories. Yet they have become the de facto standard for analyzing a system's requirements, which is why the course combines them with object-oriented analysis.
Worked example: a brief "Borrow a Book" use case.
- Actor: Patron
- Goal: borrow a book from the library
- Main scenario:
- Patron requests to search for a book.
- System shows matching titles.
- Patron selects a book and requests to check it out.
- System records the loan (which book, which patron, the due date) and confirms.
What this teaches: the requirement is described from the user's point of view as a sequence of uses, which stakeholders can read and agree on — before any object or class is invented. It directly supports the earlier point that use case analysis is a de facto standard, and that it pairs with (not replaces) object-oriented analysis.
1.9.3 Modeling is abstraction of reality
The session tied modeling back to abstraction: when we model, we are making an abstraction of reality. The software objects we create are not exactly the same as the real-world objects they stand for. A real-world object has a huge number of feature, but the software object has only the limited set we chose to implement. The professor used the comparison of an online product listing — a product may have a picture, a 3D view, a look and feel — but in software we store only the properties that matter to the system. Modeling therefore means abstracting the real world into a software model that captures what is relevant and drops the rest, and doing that modeling for both analysis and design is what this course teaches.
Connect the loop back to abstraction. In Section 1.5 abstraction was "ignore what is not needed." Modeling is abstraction applied to the whole system: the software model is a simplified picture of reality, keeping the relevant features and dropping the rest. The product listing example makes it concrete — the real product has a picture, a 3D view, a look and feel, but the software object stores only what the system needs. So every diagram and class you will draw is an abstraction of reality, and knowing what to keep is exactly the skill this course trains.
Pitfalls to avoid with this section:
- Assuming a model must copy reality fully. A domain model is not a software object and not a full copy of the world; it is a visualization of noteworthy concepts. Expecting a software model to include every feature of a real object is the opposite of abstraction.
- Thinking UML itself is the design skill. UML is only a notation. The valuable skill is deciding how responsibilities are assigned to objects; drawing UML notation well without knowing how to design well just produces neatly drawn bad designs.
- Forgetting use cases are not object-oriented per se. They are the de facto standard requirements tool, but they describe stories of use, not objects. Keeping that straight prevents confusion when the course combines use cases with OO analysis.
- Believing pictures replace understanding. Diagrams communicate fast, but the persuasive power of a diagram does not make the underlying design correct.
Recap + bridge. UML is the unified, shared notation for drawing models, preferred because stakeholders grasp pictures faster than prose; use case analysis describes requirements as stories of user use and is the de facto standard (even though it is not itself object-oriented); and all modeling is abstraction of reality. With the vocabulary (objects, classes, patterns of reuse) and the shared notation in place, the final foundational idea ties it together: end-to-end, proven recipes for solving recurring problems — design patterns, Section 1.10.
Real-world domain connection. UML and use case analysis are exactly what industry uses to align developers with non-technical stakeholders. In a bank, airline, or hospital project, a use case diagram and a couple of story-level use cases let executives and end users confirm "yes, that is the system" long before code exists, while the same UML class/sequence diagrams later guide the developers. This closed loop — pictures to agree on requirements, pictures to design the solution — is the visual modeling the course teaches throughout.
1.10 Design Patterns
1.10.1 Patterns as repeatable solutions
Hook. Inheritance showed you can reuse a class; can you reuse a whole solution to a class of problems, so that every new system does not start from a blank page? Yes — that is the idea behind a design pattern, and it is the final foundation piece of this lecture.
A design pattern is a general, repeatable solution to a recurring problem — a collection of problem and solution. The idea is that every software system need not be designed from scratch: for a given kind of problem there are proven, reusable solutions, and we learn those best practices instead of reinventing them. A pattern is generic, so you apply it by adapting a general solution to a specific case.
Formalize a pattern as a problem–solution pair.
A pattern is documented as a pair:
- the problem — a recurring situation, stated generically;
- the solution — a proven, reusable structure for that situation.
Because the solution is generic, you do not copy it verbatim; you adapt it to the specifics of your case. The pattern is a named recipe you recall ("this looks like the Observer problem") rather than a design you invent from zero each time.
A pattern is also not about small repetitive code — it is about design-level structure: which objects exist, and which is responsible for what — exactly the responsibility-assignment skill introduced in Section 1.4.
The professor linked this to engineering broadly: in every engineering discipline there are patterns — the way dresses have their patterns, the way buildings repeat structures. Just as in any field, repeating problems get repeating solutions, and in software those solutions get written down and documented so others can reuse them.
Restating and extending the professor's "patterns in every field" analogy. Tailors reuse a dress pattern to make many different dresses; builders reuse structural patterns in bridge and building design. The same logic runs through software: a problem that appears again and again (login/authentication, publish/subscribe, caching) gets a solution that works again and again, documented so others can apply it instead of re-deriving it. The analogy is exact in spirit — a pattern is a reusable template adapted to each new instance — and it breaks only in that software patterns are about object responsibilities and collaborations rather than cloth or steel.
1.10.2 The history and the people
Two sets of names matter here. The idea of a pattern in design is credited to Christopher Alexander (in architecture), who is regarded as the father of the pattern concept. But the software community knows patterns chiefly through the landmark 1994 book co-authored by Gamma and colleagues ("the Gang of Four"), published using C++ for its examples, which collected 23 or 24 patterns and made them widely known. So, in software engineering, a pattern is defined as a problem-and-solution pair, documented generically, ready to be specialized.
A final framing from the session ties several threads together: the best way to approach object orientation is to look for best practices — proven, repeatable solutions — and to apply them rather than build everything from scratch. That is the spirit behind both inheritance's reuse and the entire field of design patterns.
Name the two anchor references for the history.
- Christopher Alexander — architect credited as the originator of the pattern concept (in architecture): patterns as recurring structures and solutions.
- The "Gang of Four" (GoF) — the four authors (Gamma, Helm, Johnson, Vlissides) of the landmark 1994 book Design Patterns, whose C++-based catalog collected the famous set of 23 patterns and popularized software design patterns widely.
These two names settle who invented a pattern idea (Alexander) and who brought it to software (the GoF catalog) — a distinction the professor draws so you keep the history straight.
Pitfalls and scope to avoid with this section:
- Treating a pattern as copy-paste code. A pattern is a generic structure to adapt, not ready-made code to paste. Applying it blindly without adapting to your problem creates the wrong design.
- Forgetting who did what. Christopher Alexander originated the pattern concept (architecture); the Gang of Four brought a software catalog of 23 patterns to prominence. Mixing these up loses points on the history of the field.
- Believing patterns replace good judgment. A pattern is a proven best practice, but you still need to recognize which problem you actually face and whether the pattern fits — the responsibility-assignment skill remains the real underlying ability.
- Thinking every system must use many patterns. Patterns are tools for recurring problems; forcing in patterns "because they are fashionable" adds needless complexity.
Recap + bridge — and the lecture's closing thread. A design pattern is a general, repeatable problem–solution pair, credited to Christopher Alexander and made famous in software by the Gang of Four's 23-pattern catalog; its spirit is the same as inheritance's — reuse. This closes the foundation: paradigm, lifecycle, analysis vs design, objects/classes/state/behavior, abstraction, encapsulation, inheritance, polymorphism, interface, UML + use cases, patterns. Every later topic in this course (GRASP, Object Design, and the individual patterns) is built on exactly these building blocks and this reuse mindset.
Real-world domain connection. Design patterns are the backbone of real software reuse. A news app uses the Observer pattern to update subscribers when articles change; a payroll system uses Strategy or Command to swap payment rules; a logging framework uses a Singleton for a single shared logger. Companies build internal libraries of reusable, tested components on exactly this idea — so every software need not be designed from scratch, which is the closing theme of this entire first lecture.
Exam Guidance Summary
This first session is an introduction, so it contained no mark distributions or question-type guidance — but it set expectations that shape how you should prepare for the rest of the course and its assessments:
Exam note: the core definitions are the highest-value material. The course is built on vocabulary: know these cold, because every later diagram and pattern rests on them.
- Object — state + behavior.
- Class — a template or blueprint; a user-defined data type.
- Abstraction — ignoring what is not needed for the problem.
- Encapsulation — packaging state + behavior with controlled access (public/private/protected).
- Inheritance — generalization and specialization, for reuse.
- Polymorphism — one interface, many implementations.
- Interface — a contract / black box between a class and its users.
What to be ready to apply and reason about:
- The What/How split: analysis is the problem side and asks what; design is the solution side and answers how. Be ready to apply it to a concrete case, as was done with the library management system.
- Identify methods, not just attributes. The professor explicitly flagged "the difficult part is methods" — practice reasoning about what behavior each object must expose, because this is where most confusion lives.
- Test and clarify requirements. Requirements must be testable and unambiguous; the SRS is written from the developer's perspective and signed as an agreement with the customer. Expect this reasoning (and the caution that most project failures come from misunderstood requirements) to recur throughout the course.
- The development models — waterfall vs iterative vs spiral vs Unified Process — and why iterative models like the Unified Process are preferred, since the course and textbook are built around the Unified Process.
- The class notation — a rectangle with class name, attributes, and methods, as introduced with the
Bookexample.
How to study for this course. Writing your own answers matters: the professor gave explicit study advice not to copy definitions from the internet verbatim — form your own understanding, because articulating your own answer leaves a longer-lasting impression. The classroom expectation is part of this too: sessions are built around doubt-clearing and interaction rather than one-way delivery, so coming prepared to ask questions on the recorded material is itself a form of study advice.
Key Industry Applications
The real-world connections woven through this session, gathered here for quick reference:
- Ubiquitous software. Banking transactions, checking account balances, transfers done on mobile phones, railway reservation systems, and air-flight ticket booking are all software systems — everyday systems that object-oriented design helps build. The professor's refrain is that "everywhere software is there."
- Java and C++ in industry. Java is a leading industrial language (originally started by Sun and now maintained by Oracle), and the course teaches with it because its concepts are widely accepted; C++ knowledge transfers easily to Java. On the job you will meet both.
- Pattern catalogs. The Gang of Four design-pattern catalog (1994) and Christopher Alexander's original pattern idea are the commercial and engineering foundation of reuse; companies build libraries of reusable components on exactly this idea.
- Visual modeling with stakeholders. Because clients do not read long text documents, industry uses graphical models (UML) and use case analysis — the de facto standard — to communicate requirements with end users.
- Iterative development. Industry has largely abandoned the waterfall model in favor of iterative models such as the Unified Process, and historical failure data (the Standish Report of 1995) is used to argue for disciplined requirements handling in real projects.
- Abstraction in e-commerce. Product listings carry only the properties that matter (images, 3D views, look and feel), a concrete example of abstracting a real product into a limited software object.
- Everyday modeling objects. Concepts such as a course, a banking transaction, a booking, or a reservation are software objects even though they are not physical — the same abstraction principle applies to businesses that model invisible ideas as objects.
The through-line to carry away. Every one of these applications depends on the same handful of ideas from this lecture: model the world as objects, split analysis (what) from design (how), abstract and encapsulate, reuse through inheritance and patterns, and communicate with stakeholders visually through UML and use cases. When you meet a real system — a bank app, an airline booking site, an e-commerce catalog — you are looking at these principles at work.
OODAP Lecture 1 notes · Object-Oriented Analysis and Design
Sections Breakdown
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
1.1 The Object-Oriented Paradigm
Must know: Object orientation is a paradigm in which the world is modeled as objects, each capsule combining state (attributes) and behavior (methods); it differs from functional/structured decomposition where data and functions were separate. The course teaches with Java, not Java itself.
Common pitfall: Confusing object orientation with writing code in Java; confusing teaching with a language for teaching a language.
Self-check: What is the single change that defines object orientation compared with functional decomposition?
Connections: 1.1.2, 1.4
1.2 The Software Engineering Lifecycle and Development Models
Must know: The lifecycle phases and the four development models (waterfall, iterative, spiral, Unified Process). Iterative models are preferred because requirements are rarely fully known upfront; the Standish Report links most failures to misunderstood requirements.
Common pitfall: Thinking of the lifecycle as a strict linear sequence when in practice phases overlap and testing starts early.
Self-check: Why has the waterfall model been largely abandoned in practice?
Connections: 1.2.1, 1.3
1.3 Analysis versus Design
Must know: Analysis = problem side = what is required (with investigation/understanding, producing a testable signed SRS); Design = solution side = how (creative, constrained, expressed in objects). Apply to a concrete case like library management.
Common pitfall: Confusing analysis with merely collecting requirements; designing before understanding the problem; or collecting wishes without an unambiguous, testable spec.
Self-check: In a library management system, what belongs to analysis and what to design?
Connections: 1.2, 1.5
1.4 Objects, Classes, State, and Behavior
Must know: Object = state (attributes) + behavior (methods); class = template/blueprint, a user-defined data type; class rectangle = name/attributes/methods. Signed 32-bit int domain is [-2^31, 2^31-1]. Identifying methods is the difficult part.
Key formula:
Common pitfall: Conflating class and object; modeling too much state without abstracting; under-investing in identifying methods; forgetting that concepts (course, transaction, reservation) can be objects.
Self-check: What are the state and behavior of a course object?
Connections: 1.1.2, 1.5
1.5 Abstraction and Encapsulation
Must know: Abstraction = ignoring features not needed for the problem (deciding what to keep); encapsulation = packaging state+behavior with controlled access via public/private/protected (information hiding). The difficult part of building a class is identifying methods.
Common pitfall: Treating abstraction as arbitrary omission; making everything public; equating encapsulation with privacy alone; forgetting methods are the hard part.
Self-check: How do public, private, and protected control access in encapsulation?
Connections: 1.1.2, 1.4, 1.6
1.6 Inheritance
Must know: Inheritance defines a new class by reusing a parent's content. Generalization = broader category (Vehicle); specialization = narrower refinement (Car). Goal is reuse: write common code once, subclass adds unique parts. Drawn as a tree.
Common pitfall: Using inheritance without a true is-a relationship; confusing generalization and specialization directions; treating inheritance as the only reuse mechanism.
Self-check: Is a Truck a generalization or a specialization of Vehicle?
Connections: 1.7, 1.10
1.7 Polymorphism
Must know: Polymorphism = one interface, multiple implementations; the caller does not care which implementation it gets. It supplies flexibility/openness to change and is the mechanism through which inheritance is realized.
Common pitfall: Conflating polymorphism with inheritance; confusing conceptual interface with the Java keyword only; forgetting the caller's interface-only viewpoint.
Self-check: Using the USB analogy, what is the interface and what are the implementations?
Connections: 1.6, 1.8
1.8 Interfaces
Must know: Interface = black-box contract between a class and its users; separates stable interface from changeable hidden implementation. In Java, interface enables multiple inheritance of behavior.
Common pitfall: Conflating the two meanings of interface (conceptual black-box contract vs Java construct enabling multiple inheritance).
Self-check: How does Java use interfaces to achieve multiple inheritance?
Connections: 1.5, 1.7
1.9 UML and Use Case Analysis
Must know: UML = unified notation for communicating models; use case analysis = requirements from end-user stories of use (de facto standard, not itself object-oriented); modeling = abstraction of reality.
Common pitfall: Assuming a model must copy reality; thinking UML notation itself is the design skill; forgetting use cases are not object-oriented per se.
Self-check: Why is use case analysis called the de facto standard despite not being object-oriented?
Connections: 1.5, 1.10
1.10 Design Patterns
Must know: Design pattern = general, repeatable problem-and-solution pair, adapted to specific cases. Christopher Alexander originated the pattern concept; the Gang of Four's 1994 catalog (23 patterns) popularized software patterns.
Common pitfall: Treating a pattern as copy-paste code; conflating Alexander (originator) with the GoF (software catalog); forcing patterns in unnecessarily.
Self-check: Who originated the pattern concept and who popularized software design patterns?
Connections: 1.6, 1.9
Exam Guidance Summary
Must know: Core definitions (object, class, abstraction, encapsulation, inheritance, polymorphism, interface), What/How split, methods are the difficult part, testable/unambiguous SRS, development models and Unified Process, class rectangle notation.
Common pitfall: Copying definitions verbatim from the internet rather than forming your own understanding.
Self-check: What is the single most important vocabulary list to remember from this first session?
Connections: 1.1, 1.2, 1.3, 1.4
Key Industry Applications
Must know: Real-world anchors: ubiquitous software, Java/C++ in industry, pattern catalogs for reuse, visual UML/use-case modeling with stakeholders, iterative development and Standish Report, e-commerce abstraction, non-physical business objects.
Self-check: Name three everyday systems built from object-oriented software.
Connections: 1.1, 1.2, 1.5, 1.9, 1.10
Was this lecture useful?
BitsNotes AI Assistant
Subject Notes AssistantConfigure AI Chat
Choose how to access the chatbotSigned in as
Powered by BitsNotes — 20 messages per day. No API key needed. Want unlimited access? Use "Bring Your Own Key" mode.
Sign in to use AI Chat
Get 20 free AI messages per day to ask questions about your lecture notes. Sign in with Google or GitHub — it takes 5 seconds.
Sign In to BitsNotesSwitch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.