Ruby Method Overriding
Redefining inherited methods in child classes
🔄 What is Method Overriding?
Method overriding allows a child class to provide a specific implementation of a method already defined in its parent class, enabling customized behavior while maintaining inheritance.
# Basic method overriding example
class Animal
def speak
"Some sound"
end
end
class Dog < Animal
def speak
"Woof!"
end
end
dog = Dog.new
puts dog.speak
Output:
Woof!
Key Overriding Concepts
Basic Override
Replace parent method completely
class Cat < Animal
def speak
"Meow!"
end
end
Using super
Call parent method from child
def speak
super + " loudly"
end
Extend Behavior
Add functionality to parent method
def initialize(name)
super(name)
@extra = "value"
end
Polymorphism
Different behavior, same interface
animals.each do |a|
puts a.speak
end
🔹 Simple Method Override
Override a parent method to change its behavior in the child class. This is the most common form of method overriding where you completely replace the parent's implementation.
class Vehicle
def start
"Vehicle starting..."
end
end
class Car < Vehicle
def start
"Car engine starting with key!"
end
end
class Motorcycle < Vehicle
def start
"Motorcycle starting with button!"
end
end
car = Car.new
bike = Motorcycle.new
puts car.start
puts bike.start
Output:
Car engine starting with key! Motorcycle starting with button!
🔹 Using super Keyword
The super keyword calls the parent class method, allowing you to extend rather than completely replace functionality. This is useful when you want to keep the parent's behavior and add more to it.
class Employee
def initialize(name)
@name = name
end
def details
"Employee: #{@name}"
end
end
class Manager < Employee
def initialize(name, department)
super(name) # Calls parent initialize
@department = department
end
def details
super + ", Department: #{@department}"
end
end
manager = Manager.new("Alice", "Sales")
puts manager.details
Output:
Employee: Alice, Department: Sales
🔹 Override with Parameters
You can override methods that accept parameters and even change the parameter list. However, it's best practice to maintain the same interface for consistency.
class Shape
def area(dimension)
dimension * dimension
end
end
class Rectangle < Shape
def area(length, width)
length * width
end
end
class Circle < Shape
def area(radius)
3.14 * radius * radius
end
end
rect = Rectangle.new
circle = Circle.new
puts "Rectangle area: #{rect.area(5, 3)}"
puts "Circle area: #{circle.area(4)}"
Output:
Rectangle area: 15 Circle area: 50.24
🔹 Polymorphism Example
Method overriding enables polymorphism, where different objects respond to the same method call in their own way. This allows you to write flexible, reusable code that works with multiple object types.
class Payment
def process
"Processing payment..."
end
end
class CreditCard < Payment
def process
"Processing credit card payment with verification"
end
end
class PayPal < Payment
def process
"Processing PayPal payment via API"
end
end
class Cash < Payment
def process
"Processing cash payment - no online transaction"
end
end
# Polymorphism in action
payments = [CreditCard.new, PayPal.new, Cash.new]
payments.each do |payment|
puts payment.process
end
Output:
Processing credit card payment with verification Processing PayPal payment via API Processing cash payment - no online transaction