Menu
Coddy logo textTech

Information Hiding

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 34 of 110.

Information hiding is the principle behind encapsulation - the idea that a class should hide its internal workings and only expose what's necessary. You've learned the mechanics (private fields, getters, setters), but the real goal is designing classes that are easy to use and hard to misuse.

Consider a class that manages a user's password. The internal storage and hashing logic should be completely hidden:

class UserAccount {
  String _username;
  String _passwordHash;
  
  UserAccount(this._username, String password) 
      : _passwordHash = _hashPassword(password);
  
  static String _hashPassword(String password) {
    return 'hashed_$password';  // Simplified example
  }
  
  bool verifyPassword(String password) {
    return _passwordHash == _hashPassword(password);
  }
  
  String get username => _username;
}

External code never sees the password hash or knows how it's stored. They simply call verifyPassword(). This separation means you could completely change the hashing algorithm without affecting any code that uses this class.

The key insight is to think about your class from the outside in.

Ask yourself: "What does someone using this class actually need?" Expose only that, and keep everything else private. This creates a clear boundary between what your class does (its public interface) and how it does it (its private implementation).

challenge icon

Challenge

Easy

Let's build a secure wallet system that demonstrates information hiding in action. You'll create a digital wallet that manages a user's balance and transaction history, keeping all the sensitive internal details completely hidden from external code.

You'll organize your code into two files:

  • wallet.dart: Create a Wallet class that securely manages money. The wallet should store the owner's name publicly, but everything else should be hidden behind a clean public interface:
    • The internal balance and transaction log should be private - external code should never see how you store or track money
    • A private method should handle recording transactions internally (storing entries like "Deposit: $50.0" or "Withdrawal: $30.0")
    • Provide a public deposit(double amount) method that adds money (only if the amount is positive) and records the transaction internally
    • Provide a public withdraw(double amount) method that removes money only if there are sufficient funds and the amount is positive, recording the transaction internally. Return true if successful, false otherwise
    • Provide a public getter balance that returns the current balance (read-only access)
    • Provide a public method getTransactionCount() that returns how many transactions have been recorded (without exposing the actual transaction list)
    • Provide a public method getLastTransaction() that returns the most recent transaction string, or "No transactions" if none exist
    • Include a printSummary() method that displays the wallet status
  • main.dart: Import your wallet and demonstrate how information hiding creates a clean, safe interface:
    • Create a wallet for owner "Sarah"
    • Deposit 100.0
    • Deposit 50.0
    • Attempt to withdraw 200.0 and print "Withdrawal of 200.0: [success/failed]" based on the result
    • Withdraw 30.0 and print "Withdrawal of 30.0: [success/failed]"
    • Call printSummary()
    • Print "Transaction count: [count]"
    • Print "Last transaction: [transaction]"

The printSummary() method should print:

=== Wallet Summary ===
Owner: [ownerName]
Balance: $[balance]

Notice how external code can interact with the wallet through clear, purposeful methods without ever knowing how the balance is stored or how transactions are tracked internally. The implementation details are completely hidden - you could change how transactions are stored without affecting any code that uses the wallet.

Expected output:

Withdrawal of 200.0: failed
Withdrawal of 30.0: success
=== Wallet Summary ===
Owner: Sarah
Balance: $120.0
Transaction count: 3
Last transaction: Withdrawal: $30.0

Cheat sheet

Information hiding is the principle behind encapsulation - hiding a class's internal workings and exposing only what's necessary.

Design classes from the outside in: expose only what users need, keep everything else private. This creates a clear boundary between the public interface (what the class does) and private implementation (how it does it).

Example of information hiding with a password manager:

class UserAccount {
  String _username;
  String _passwordHash;
  
  UserAccount(this._username, String password) 
      : _passwordHash = _hashPassword(password);
  
  static String _hashPassword(String password) {
    return 'hashed_$password';
  }
  
  bool verifyPassword(String password) {
    return _passwordHash == _hashPassword(password);
  }
  
  String get username => _username;
}

External code never sees the password hash or storage mechanism - they only use verifyPassword(). This allows changing the internal implementation without affecting external code.

Try it yourself

import 'wallet.dart';

void main() {
  // TODO: Create a wallet for owner "Sarah"
  
  // TODO: Deposit 100.0
  
  // TODO: Deposit 50.0
  
  // TODO: Attempt to withdraw 200.0 and print result
  // Format: "Withdrawal of 200.0: [success/failed]"
  
  // TODO: Withdraw 30.0 and print result
  // Format: "Withdrawal of 30.0: [success/failed]"
  
  // TODO: Call printSummary()
  
  // TODO: Print transaction count
  // Format: "Transaction count: [count]"
  
  // TODO: Print last transaction
  // Format: "Last transaction: [transaction]"
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming