Inheritance, super and Method Visibility
17.1 Inheritance
Ruby supports single inheritance only. Use modules for shared behavior.
super (bare) forwards all arguments. super() passes no arguments. super(a, b) passes specific ones.
class Animal
attr_reader :name
def initialize(name) = @name = name
def speak = "..."
def describe = "#{name} says #{speak}"
end
class Dog < Animal
attr_reader :breed
def initialize(name, breed)
super(name) # call the parent's initialize with explicit args
@breed = breed
end
def speak = "Woof"
end
class Puppy < Dog
def speak = "#{super} (squeaky)" # bare super passes the same arguments
end
Puppy.new("Bit", "Lab").describe # "Bit says Woof (squeaky)"
Puppy.superclass; Puppy.ancestors
Dog < Animal # true
Puppy.instance_method(:speak).owner17.2 Method Visibility
Anywhere (default) Instances of the same class (or subclasses), with an explicit receiver allowed
Only within the object, without an explicit receiver (except self.setter=)
class Account
def initialize(balance) = @balance = balance
def transfer_to(other, amount)
return false unless sufficient?(amount)
other.receive(amount) # protected: callable from the same class family
@balance -= amount
end
def >(other) = balance > other.balance
protected
attr_reader :balance
def receive(amount) = @balance += amount
private
def sufficient?(amount) = @balance >= amount
endprivate def helper = :secret # inline form
private_class_method :new # e.g., for singletons/factories
public_send(:name) # respects visibility; send ignores it17.3 Abstract Methods and Template Method
class Report
def generate = [header, body, footer].join("\n")
def header = "=== #{title} ==="
def footer = "Generated #{Time.now}"
def title = raise(NotImplementedError, "#{self.class} must implement title")
def body = raise(NotImplementedError)
end
class SalesReport < Report
def title = "Sales"
def body = "Total: $1000"
end