Classes and objects
In procedural programming we write a list of steps and functions. In object-oriented programming (OOP) we group data and the code that works on it into objects.
- A class is a blueprint (a plan). It says what data and actions its objects have.
- An object (or instance) is one real thing made from the class.
- Attributes (fields) are the data an object keeps, like colour and speed.
- Methods are functions that belong to the class, like accelerate().
class Car:
def __init__(self, colour):
self.colour = colour
self.speed = 0
def accelerate(self, amount):
self.speed += amount
car1 = Car("red")
car2 = Car("yellow")
car1.accelerate(20)
print(car1.speed, car2.speed) # 20 0
Constructors, self, and class vs instance variables
The constructor runs automatically when an object is made. In Python it is __init__; in Java it has the same name as the class. It gives the new object its starting values.
self (Python) or this (Java) means "this particular object". self.speed is the speed of the object the method was called on.
- Instance variable: each object has its own copy (colour, speed).
- Class variable (
staticin Java): one copy shared by all objects, likewheels = 4or a counter of cars made.
A method signature is the method name plus its parameter list, e.g. accelerate(amount). In Java: public void accelerate(int amount).
// Java
public class Car {
private String colour;
private int speed;
public Car(String colour) { this.colour = colour; this.speed = 0; }
public void accelerate(int amount) { speed += amount; }
}
Encapsulation and abstraction
Encapsulation means keeping an object's data inside it and letting the outside world change it only through methods. We make attributes private (Java private; Python name starting with __) and give getter and setter methods that can check values. For example, a bank account's withdraw() refuses to go below zero.
Abstraction means showing only what the user needs and hiding the details. You press a car's accelerator without knowing how the engine burns fuel. In code, a class gives simple methods and hides the complex parts. An abstract class or interface lists methods that child classes must provide.
Inheritance and polymorphism
Inheritance: a subclass (child) is built from a superclass (parent). It gets all the parent's attributes and methods and can add more. This is an "is-a" link: an ElectricCar is a Car.
Polymorphism ("many forms"): the same method name works differently for different classes. A child class can override a parent method with its own version.
class ElectricCar(Car):
def __init__(self, colour):
super().__init__(colour)
self.battery = 100
def describe(self): # overrides Car.describe
return "electric, battery " + str(self.battery)
for c in [Car("red"), ElectricCar("blue")]:
print(c.describe()) # each answers in its own wayDesigning with objects
A UML class diagram draws each class as a box with three parts: name, attributes, methods (+ public, − private). Composition/aggregation is a "has-a" link: a Car has an Engine. OOP makes code reusable, easier to test and easier for teams to share.
Try it
Pick something at home, like a mobile phone. Write its class: 3 attributes and 2 methods. Then write two objects with different values.
Key formulas and definitions
- Class: blueprint listing attributes + methods
- Object / instance: one thing made from a class, e.g. car1 = Car("red")
- Constructor: __init__ (Python), ClassName(...) (Java)
- Encapsulation: private data + public methods (getters/setters)
- Inheritance: class Child(Parent): an "is-a" link; super() calls the parent
- Polymorphism: same method name, different behaviour (overriding)
- Abstraction: show what an object does, hide how
Worked examples
1. Write a class Student with name and marks, and a method is_pass() that returns True if marks ≥ 33.
class Student: def __init__(self, name, marks): self.name = name self.marks = marks def is_pass(self): return self.marks >= 33 s = Student("Asha", 72); s.is_pass() → True
2. car1 = Car("red"); car2 = car1; car2.accelerate(10). What is car1.speed?
10. car2 = car1 does not make a new object; both names point to the same object. Only Car(...) makes a new one.
3. Make a class variable that counts how many Car objects exist.
class Car: count = 0 def __init__(self, colour): self.colour = colour Car.count += 1 After Car("red") and Car("blue"), Car.count is 2.
4. Show encapsulation with a BankAccount that cannot go below zero.
class BankAccount: def __init__(self): self.__balance = 0 def deposit(self, x): if x > 0: self.__balance += x def withdraw(self, x): if x <= self.__balance: self.__balance -= x def get_balance(self): return self.__balance Outside code cannot write acc.__balance = -500.
5. Animal has speak() returning "...". Dog and Cat override it. What does the loop print? for a in [Dog(), Cat(), Animal()]: print(a.speak())
"Woof", "Meow", "...". Each object uses its own class's version: that is polymorphism.
6. Draw a UML box for class Book with private title and price and a public method apply_discount(p).
Book − title: str − price: float + apply_discount(p: float): void
Common mistakes
- Mixing up class and object: the class is the plan, the object is the thing made from it.
- Forgetting self in Python methods, e.g. def accelerate(amount) instead of def accelerate(self, amount).
- Thinking b = a copies an object. It only makes a second name for the same object.
- Using inheritance for a "has-a" link. A Car has an Engine (composition); it is not a kind of Engine.