OOP Notes
Learn how data hiding protects object internals from unauthorized access and modification, ensuring data integrity throughout your program.
If `failedAttempts` were public, anyone could reset it to bypass security. If `encryptionKey` were public, all passwords would be compromised.
## Data Hiding in Different Languages
### Java: Access Modifierspublic class Temperature { private double celsius; // Hidden data
public Temperature(double celsius) { setCelsius(celsius); // Use setter for validation }
public double getCelsius() { return celsius; }
public void setCelsius(double celsius) { if (celsius < -273.15) { // Absolute zero check throw new IllegalArgumentException( "Temperature cannot be below absolute zero (-273.15°C)"); } this.celsius = celsius; }
public double getFahrenheit() { return celsius * 9.0 / 5.0 + 32; }
public double getKelvin() { return celsius + 273.15; } }
class EncryptedMessage { private: std::string content; // Hidden std::string key; // Hidden bool encrypted; // Hidden
// Private helper methods std::string xorCipher(const std::string& text, const std::string& key) { std::string result = text; for (size_t i = 0; i < text.size(); i++) { result[i] = text[i] ^ key[i % key.size()]; } return result; }
public: EncryptedMessage(const std::string& msg, const std::string& key) : content(msg), key(key), encrypted(false) {}
void encrypt() { if (!encrypted) { content = xorCipher(content, key); encrypted = true; } }
std::string decrypt(const std::string& providedKey) { if (providedKey != key) { throw std::runtime_error("Invalid key"); } if (encrypted) { return xorCipher(content, key); } return content; }
bool isEncrypted() const { return encrypted; } };
class CreditCard: def __init__(self, number, holder, cvv): self.__number = number # Name-mangled (strongly hidden) self.__holder = holder self.__cvv = cvv self.__transactions = []
@property def masked_number(self): """Only reveals last 4 digits""" return "**--**-" + self.__number[-4:]
@property def holder(self): return self.__holder
def charge(self, amount, merchant): if amount <= 0: raise ValueError("Amount must be positive") self.__transactions.append({ "amount": amount, "merchant": merchant }) return True
def get_statement(self): """Read-only view of transactions""" return [t.copy() for t in self.__transactions] # Return copies!
card = CreditCard("4532015112830366", "John Doe", "123") print(card.masked_number) # **--**-0366
print(card.__cvv) # AttributeError!
| Aspect | Data Hiding | Abstraction |
|---|---|---|
| Focus | Restricting access to data | Simplifying complexity |
| How | Private access modifiers | Abstract classes, interfaces |
| Goal | Protect internal state | Show only relevant details |
| Example | Private `balance` field | `Shape.area()` method |
public class AudioPlayer { // Level 1: Completely hidden implementation detail private byte[] rawAudioBuffer; private int bufferPosition;
// Level 2: Hidden from world, available to subclasses protected String currentFormat; protected int sampleRate;
// Level 3: Public interface public void play(String filename) { /* ... */ } public void pause() { /* ... */ } public void stop() { /* ... */ } public int getVolume() { /* ... */ } public void setVolume(int level) { /* ... */ } }
public class Schedule { private List<String> appointments;
// BAD: Exposes internal list — caller can modify it! public List<String> getAppointments() { return appointments; // Returns the actual internal list }
// GOOD: Returns a defensive copy public List<String> getAppointments() { return new ArrayList<>(appointments); // Returns a copy }
// BETTER: Returns unmodifiable view public List<String> getAppointments() { return Collections.unmodifiableList(appointments); } }
## Common Mistakes
1. **Providing getters/setters for everything** — if every private field has public get/set, it's not truly hidden
2. **Returning references to mutable objects** — always return copies or unmodifiable views
3. **Using public fields "for performance"** — the performance difference is negligible
4. **Hiding too much** — if subclasses need data, use `protected`, not `private`
5. **Thinking data hiding is just about security** — it's about maintaining invariants and enabling change
## Key Takeaways
- Data hiding means making internal fields **inaccessible** from outside the class
- It **prevents corruption** by ensuring data is only modified through validated methods
- Use **private** for implementation details, **protected** for subclass needs, **public** for the interface
- Always return **copies** of mutable internal objects, not references to them
- Data hiding enables you to **change implementation** without breaking external code
- It's not paranoia — it's good engineering that prevents bugs at scaleExam Focus
Revise definitions, diagrams, examples, and short-answer points for Data Hiding in OOP.
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, encapsulation, data, hiding
Related Object Oriented Programming (OOP) Topics