Hello! In this lesson, we're revisiting Encapsulation, Private Attributes, and Private Methods in Object-Oriented Programming (OOP). Imagine encapsulation as an invisible fence safeguarding a garden from outside interference, keeping data and methods secure within. Inside this garden, certain elements (Private Attributes and Methods) are accessible only from within the class.
These concepts are crucial for making your classes more robust and secure!
Encapsulation in OOP wraps up data and methods into a class
, making code organized and more secure. Encapsulation is essential for managing complexity and reducing errors in code. By restricting access to certain data and behaviors, we make our code more robust and easier to debug, as the class controls its own data without unintended interference from other parts of the program.
If you were coding a multiplayer game, for example, you could create a Player
class that encapsulates data (health
, armor
, stamina
) and methods (receive_damage
, shield_hit
, restore_health
).
Ruby1class Player 2 def initialize(health, armor, stamina) 3 @health = health 4 @armor = armor 5 @stamina = stamina 6 end 7 8 def receive_damage(damage) 9 @health -= damage # Reduce health 10 end 11 12 def shield_hit(armor) 13 @armor -= armor # Decrease armor 14 end 15 16 def restore_health(health_increase) 17 @health += health_increase # Restore health 18 end 19end 20 21player = Player.new(100, 50, 77)
Here, player
is an instance of the Player
class with encapsulated attributes and methods.
In Ruby, attributes are private by default, and accessing them from outside the class requires attr_reader
, attr_writer
, or attr_accessor
to define getter and setter methods. Here’s a quick recap:
attr_reader
: Provides read-only access to an instance variable.attr_writer
: Provides write-only access to an instance variable.attr_accessor
: Provides both read and write access.
Alternatively, for more controlled access and encapsulation, we can define custom methods to interact with attributes directly. A BankAccount
class might contain a balance
attribute that is only accessible through specific methods like deposit
or get_balance
, ensuring that the balance can’t be modified in unintended ways.
Ruby1class BankAccount 2 def initialize(account_number, balance) 3 @account_number = account_number 4 @balance = balance 5 end 6 7 def deposit(amount) 8 @balance += amount # Deposit money 9 end 10 11 def get_balance 12 @balance # Access balance 13 end 14end 15 16bank_account = BankAccount.new(1234, 100) 17puts bank_account.get_balance # Correct way to access balance 18puts bank_account.balance # Error: undefined method 'balance'
Here, balance
is encapsulated, and you access it through the method get_balance
, protecting its integrity.
Just like private attributes, Ruby makes methods private using the private
keyword within the class definition. Private methods can only be called from within the class, preventing them from being accessed externally. This is helpful for tasks that should only be controlled internally.
For example, in a bank account, only the bank should be able to add interest to an account, not the account holder. We can make the add_interest
method private to ensure that it can only be used internally:
Ruby1class BankAccount 2 def initialize(account_number, balance) 3 @account_number = account_number 4 @balance = balance 5 end 6 7 # Public method calling the private method 8 def add_yearly_interest 9 add_interest(0.02) # Adds 2% interest 10 end 11 12 private 13 14 # Private method 15 def add_interest(interest_rate) 16 @balance += @balance * interest_rate # Calculation of interest 17 end 18end 19 20bank_account = BankAccount.new(1234, 100) 21bank_account.add_yearly_interest # Works for public methods 22bank_account.add_interest(0.1) # Error: private method 'add_interest' called
Here, add_yearly_interest
is a public method that uses the private method add_interest
. This way, the interest calculation is protected from being accessed or modified outside of the class.
Great job revisiting encapsulation, private attributes, and private methods in Ruby! By understanding and applying these core principles of OOP, you can make your code more secure, concise, and reliable. Up next is hands-on practice to deepen these skills.
Keep up the good work—exciting exercises are just around the corner!