OOP Notes
Learn how access modifiers control visibility and access to class members — public, private, protected, and default access levels in Java, C++, and Python.
BankAccount acc = new BankAccount(); acc.balance = -999999; // Nothing prevents this!
// WITH access control — safe class BankAccount { private double balance; // Only this class can modify it
public void deposit(double amount) { if (amount > 0) { // Validation enforced balance += amount; } } }
| Modifier | Same Class | Same Package | Subclass | World |
|---|---|---|---|---|
| `private` | ✅ | ❌ | ❌ | ❌ |
| default (no keyword) | ✅ | ✅ | ❌ | ❌ |
| `protected` | ✅ | ✅ | ✅ | ❌ |
| `public` | ✅ | ✅ | ✅ | ✅ |
public class CreditCard { private String cardNumber; // Only this class can see this private double creditLimit; private double currentBalance;
public CreditCard(String number, double limit) { this.cardNumber = number; this.creditLimit = limit; this.currentBalance = 0; }
// Private helper — internal logic private boolean hasAvailableCredit(double amount) { return (currentBalance + amount) <= creditLimit; }
// Public interface — controlled access public boolean charge(double amount) { if (amount <= 0) return false; if (!hasAvailableCredit(amount)) return false; currentBalance += amount; return true; }
public String getMaskedNumber() { // Only shows last 4 digits return "**--**-" + cardNumber.substring(cardNumber.length() - 4); } }
### Protected
Accessible within the same class, same package, and subclasses. Use for members that subclasses need but outsiders shouldn't access.public class Vehicle { protected int speed; // Subclasses need this protected String fuelType; private String vinNumber; // Even subclasses shouldn't access this
protected void accelerate(int amount) { speed += amount; if (speed > getMaxSpeed()) { speed = getMaxSpeed(); } }
protected int getMaxSpeed() { return 100; // Default max speed } }
public class SportsCar extends Vehicle { public void turboBoost() { accelerate(50); // Can access protected method System.out.println("Speed: " + speed); // Can access protected field // System.out.println(vinNumber); // ERROR! Can't access private }
@Override protected int getMaxSpeed() { return 250; // Sports cars go faster } }
### Public
Accessible from anywhere. Use for the external interface of your class.public class Calculator { // Public methods — the interface other code uses public double add(double a, double b) { return a + b; } public double subtract(double a, double b) { return a - b; } public double multiply(double a, double b) { return a * b; }
public double divide(double a, double b) { if (b == 0) throw new ArithmeticException("Cannot divide by zero"); return a / b; } }
class Employee { private: // Section starts here std::string ssn; // Very sensitive double salary;
void calculateTax() { // Internal helper // ... }
protected: // Section starts here std::string department; int employeeId;
void transferDepartment(std::string newDept) { department = newDept; }
public: // Section starts here std::string name;
Employee(std::string name, int id, double salary) : name(name), employeeId(id), salary(salary) {}
void displayInfo() const { std::cout << name << " (ID: " << employeeId << ")" << std::endl; // Can access private members here }
double getSalary() const { return salary; } };
class Account: def __init__(self, owner, balance): self.owner = owner # Public — no underscore self._transaction_log = [] # Protected — single underscore (convention) self.__balance = balance # Private — double underscore (name mangling)
def deposit(self, amount): """Public method""" if amount > 0: self.__balance += amount self._log_transaction(f"Deposit: +${amount}")
def _log_transaction(self, message): """Protected method — subclasses can use, but outsiders shouldn't""" self._transaction_log.append(message)
def __validate_amount(self, amount): """Private method — only this class should use""" return amount > 0
acc = Account("Alice", 1000) print(acc.owner) # Works — public print(acc._transaction_log) # Works but discouraged — protected by convention
print(acc.__balance) # AttributeError! Name mangling applied
print(acc._Account__balance) # Works but VERY bad practice
## Choosing the Right Access Level
Follow this decision process:
1. **Start with private** — make everything private by default
2. **Make protected** only if subclasses genuinely need direct access
3. **Make public** only for the class's external interfacepublic class ShoppingCart { // Private: internal implementation private List<Item> items = new ArrayList<>(); private double taxRate = 0.08;
// Private: helper methods private double calculateSubtotal() { return items.stream().mapToDouble(Item::getPrice).sum(); }
// Public: the interface users need public void addItem(Item item) { items.add(item); }
public void removeItem(Item item) { items.remove(item); }
public double getTotal() { double subtotal = calculateSubtotal(); return subtotal + (subtotal * taxRate); }
public int getItemCount() { return items.size(); } }
| - **Private** | Internal implementation only — strongest protection |
| - **Protected** | For inheritance hierarchies — subclass access |
| - **Public** | External interface — what the world sees |
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Access Modifiers.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Object Oriented Programming (OOP) topic.
Search Terms
object-oriented-programming, object oriented programming (oop), object, oriented, programming, oop, basics, access
Related Object Oriented Programming (OOP) Topics