Object-Oriented Programming
## Learning Objectives
- Create classes and objects
- Implement inheritance
- Use modules as mixins
- Control access to methods
## Classes
### Defining a Class
```ruby
class Dog
# Initialize is the constructor
def initialize(name, breed)
@name = name # Instance variable
@breed = breed
end
# Instance method
def bark
"#{@name} says Woof!"
end
# Getter
def name
@name
end
# Setter
def name=(value)
@name = value
end
end
# Create object
dog = Dog.new("Buddy", "Golden Retriever")
puts dog.bark # "Buddy says Woof!"
```
### Attribute Methods
```ruby
class Dog
attr_reader :name # Read only
attr_writer :name # Write only
attr_accessor :breed # Read and write
def initialize(name, breed)
@name = name
@breed = breed
end
end
dog = Dog.new("Buddy", "Golden Retriever")
puts dog.name # "Buddy"
dog.name = "Max"
puts dog.name # "Max"
```
### Self Keyword
```ruby
class Counter
@@count = 0
def initialize
@@count += 1
end
def self.total
@@count
end
def instance_id
self.object_id
end
def increment
self.class.increment_count
end
private
def self.increment_count
@@count += 1
end
end
```
## Instance vs Class Variables
```ruby
class BankAccount
@@interest_rate = 0.05 # Class variable (shared)
def initialize(balance)
@balance = balance # Instance variable (per object)
end
def interest
@balance * @@interest_rate
end
end
```
## Methods
### Public, Private, Protected
```ruby
class User
def public_method
"I can be called from anywhere"
end
private
def private_method
"I can only be called internally"
end
protected
def protected_method
"I can be called by other instances of same class"
end
end
```
### Private with Arguments
```ruby
class Calculator
def operations(a, b)
add(a, b) + subtract(a, b)
end
private
def add(a, b)
a + b
end
def subtract(a, b)
a - b
end
end
```
## Inheritance
### Basic Inheritance
```ruby
class Animal
def initialize(name)
@name = name
end
def speak
"..."
end
end
class Dog < Animal
def speak
"Woof!"
end
end
class Cat < Animal
def speak
"Meow!"
end
end
dog = Dog.new("Buddy")
puts dog.speak # "Woof!"
```
### Super
```ruby
class Vehicle
def initialize(make, model)
@make = make
@model = model
end
def info
"#{@make} #{@model}"
end
end
class Car < Vehicle
def initialize(make, model, year)
super(make, model) # Call parent initialize
@year = year
end
def info
"#{super} (#{@year})"
end
end
```
### Abstract Classes
Ruby doesn't have abstract classes natively, but you can simulate:
```ruby
class AbstractClass
def initialize
raise NotImplementedError, "Subclass must implement"
end
end
```
## Modules
### As Namespace
```ruby
module MathUtils
class Calculator
def add(a, b)
a + b
end
end
end
calc = MathUtils::Calculator.new
puts calc.add(2, 3)
```
### As Mixin
```ruby
module Walkable
def walk
"#{name} is walking"
end
end
class Person
include Walkable
def initialize(name)
@name = name
end
attr_reader :name
end
person = Person.new("Alice")
puts person.walk
```
### Multiple Mixins
```ruby
module Flyable
def fly
"#{name} is flying"
end
end
module Swimmable
def swim
"#{name} is swimming"
end
end
class Duck
include Flyable
include Swimmable
def initialize(name)
@name = name
end
attr_reader :name
end
duck = Duck.new("Donald")
puts duck.fly
puts duck.swim
```
### Module Methods
```ruby
module Config
@debug = false
def self.debug
@debug
end
def self.debug=(value)
@debug = value
end
# Alternative syntax
class << self
attr_accessor :debug
end
end
Config.debug = true
puts Config.debug
```
## Object Lifecycle
```ruby
class Example
puts "Class definition loaded"
def initialize
puts "Object created"
end
def finalize
puts "Object about to be garbage collected"
end
end
# Note: Ruby doesn't have destructors,
# use at_exit or ObjectSpace for cleanup
```
## Duck Typing
Ruby uses duck typing - if it walks like a duck...
```ruby
class Duck
def quack
"Quack!"
end
end
class Person
def quack
"I'm pretending to be a duck"
end
end
def make_it_quack(duck)
puts duck.quack
end
make_it_quack(Duck.new) # "Quack!"
make_it_quack(Person.new) # "I'm pretending to be a duck"
```
## Constants in Classes
```ruby
class Math
PI = 3.14159
E = 2.71828
class << self
attr_reader :version
end
end
puts Math::PI # 3.14159
```
## Class Methods vs Instance Methods
```ruby
class Example
# Instance method
def instance_method
"Called on instance"
end
# Class method (self.method)
def self.class_method
"Called on class"
end
# Alternative class method syntax
class << self
def another_class_method
"Also called on class"
end
end
end
Example.class_method # "Called on class"
Example.new.instance_method # "Called on instance"
```
## Method Lookup
```ruby
module A
def method
"A"
end
end
module B
def method
"B"
end
end
class C
include A
include B # B wins (last included first)
end
class D < C
end
puts D.new.method # "B" (lookup chain: D -> C -> B -> A -> Object)
```
## Summary
- `class` defines a class, `initialize` is the constructor
- `attr_accessor`, `attr_reader`, `attr_writer` create getters/setters
- `@variable` is instance variable, `@@variable` is class variable
- `self.method` defines class method
- `super` calls parent method
- `include` adds module methods as instance methods
- `extend` adds module methods as class methods
- Access control: `public`, `private`, `protected`
- Ruby uses duck typing (no interfaces needed)
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →