Why OOP exists
A small program can be a list of instructions. A large one cannot — with thousands of variables floating in one scope, every change risks breaking something far away.
OOP's answer is to bundle data together with the code that operates on it, and then hide the internals so the rest of the program cannot reach in and corrupt them.
Class versus object
A class is the blueprint. An object is a house built from it. One class, many objects, each with its own values.
class Student defines that every student has a name, a roll number and a marks list. Student ali = new Student("Ali", 42) creates one actual student. Creating a second student does not disturb the first — they hold separate data in separate memory.
The four pillars
| Pillar | What it means | Why you want it |
|---|---|---|
| Encapsulation | Fields are private; access goes through methods | Nothing can put the object into an invalid state |
| Inheritance | A class extends another and reuses its members | Shared behaviour is written once |
| Polymorphism | One call, many implementations | Add new types without editing old code |
| Abstraction | Expose what it does, hide how | Callers survive changes to the internals |
Click each box. Circle and Rectangle both inherit describe() untouched, but each overrides area(). Same call, different behaviour — that is polymorphism.
Encapsulation, concretely
Make balance public and any line of code anywhere can set it to −5000. Make it private and force changes through withdraw(), and you get one place to check that the account has sufficient funds.
The rule of thumb: fields private, methods public as needed. The public methods are your contract with the rest of the program.
Polymorphism, in one line
Given a list of Shape objects, calling s.area() on each runs the circle formula for circles and the rectangle formula for rectangles — without a single if-statement. Add a Triangle class next year and that loop still works, unchanged.
Inheritance is not free
Deep inheritance chains get brittle fast — a change five levels up breaks everything below it. Prefer composition: a Car has an Engine, rather than a Car is an Engine. Use inheritance only when the child genuinely is a kind of the parent.
Classes, objects and constructors
A class is a blueprint; an object is a thing built from it. The distinction matters because a class is written once and costs nothing at run time, while every object created from it occupies its own memory and carries its own values.
Creating an object is called instantiation, and it runs a special method called the constructor. The constructor exists to leave the new object in a valid state — giving every attribute a sensible starting value, so no object can begin life half-initialised.
- CLASS
- the blueprintwritten once, uses no memory itself
- object
- an instanceeach has its own copy of the attributes
- NEW
- the constructorruns at creation to set a valid initial state
Why the validation belongs inside the class
Because balance is private, no outside code can set it to a negative number directly — every change must go through Deposit, which checks the amount first. The rule is enforced in one place rather than everywhere the account is used, so it cannot be forgotten. That is encapsulation earning its keep rather than being a formality.
Getters, setters and why attributes stay private
If attributes are private, controlled access is provided by methods — a getter to read a value and a setter to change it. A setter is not merely a wrapper: it is the place where a rule lives.
A setter can reject an invalid value, adjust related attributes to stay consistent, or record that a change occurred. None of that is possible if outside code writes to the attribute directly, which is the whole argument for keeping it private.
Not every attribute needs both. A read-only property has a getter and no setter, which makes it impossible for any code to change it after construction.
- Getter — returns the value, often with no logic at all.
- Setter — validates before assigning, and may reject the change.
- Read-only — a getter with no setter, so the value is fixed at construction.
- Derived — a getter that calculates rather than stores, so it can never fall out of step.
A setter that does no checking gains you nothing
Writing a private attribute with a setter that simply assigns whatever it is given provides no more protection than making the attribute public — it is the same access with more code. The point of the setter is the check. In an exam, describe what the setter validates, not just that one exists.
Recognising classes in a problem description
Design questions describe a system in words and ask for suitable classes. A reliable starting point is to look for the nouns: things that have both data and behaviour are usually classes, while properties of those things are usually attributes.
A library system mentions books, members and loans. Each has data worth storing and things it can do, so each is a candidate class. A book's title and ISBN are attributes rather than classes, because they carry no behaviour of their own.
Then look for the verbs, which suggest methods, and for relationships. If one thing is a kind of another, that suggests inheritance — a reference book is a kind of book. If one thing has another, that is composition rather than inheritance: a library has books, but a library is not a kind of book.
The is-a versus has-a test
- A car is a vehicle → inheritance.
- A car has an engine → composition, an attribute holding another object.
- Getting this the wrong way round produces classes that inherit from things they merely contain.
- Nouns with both data and behaviour become classes; nouns without behaviour become attributes.
- Verbs in the description usually become methods.