Leveraging Polymorphism for Backward Compatibility in Ruby

Introduction

Hello, learner! In today's exciting chapter, we will unravel Polymorphism, a prominent feature of Object-Oriented Programming (OOP). Specifically, we will study its role in maintaining backward compatibility while introducing new features. Think of it as a software update that introduces new functions without breaking the older functionality — ingenious, isn't it?

Understanding Polymorphism

Polymorphism, a principle derived from the Greek words 'poly' (many) and 'morphism' (forms), enables a variable or method to assume multiple roles — to embody various behaviors or functions determined by its data type or class.

Consider a class Bird with a method can_fly. If we create subclasses like Sparrow, Penguin, and Ostrich, we can override the can_fly method for certain subclasses. This demonstrates polymorphism in action.

class Bird    # Superclass
  def can_fly
    "Unknown"
  end
end

class Sparrow < Bird  # Subclass
  def can_fly
    "Yes, I can fly!"
  end
end

class Penguin < Bird  # Subclass
  def can_fly
    "No, I prefer swimming."
  end
end

birds = [Sparrow.new, Penguin.new]

birds.each do |bird|
  puts "#{bird.class} says: #{bird.can_fly}"
end
# Output:
# Sparrow says: Yes, I can fly!
# Penguin says: No, I prefer swimming.

Polymorphism for Backward Compatibility

When adding new features, which introduce new behaviors to some components, polymorphism ensures that the existing parts function as before, thereby retaining backward compatibility. In complex cases, we maintain an older version of the method in the superclass for legacy support while offering newer functionalities in subclasses.

Take, for instance, a MathOperations class with a multiply method that accepts two parameters. To support the multiplication of three numbers, we design a subclass, ExtendedMathOperations, and include a new multiply method in it, ensuring backward compatibility.

class MathOperations  # Superclass
  def multiply(a, b)
    a * b
  end
end

class ExtendedMathOperations < MathOperations  # Subclass
  def multiply(a, b, c = 1)
    a * b * c
  end
end

math_ops = MathOperations.new
extended_math_ops = ExtendedMathOperations.new
puts math_ops.multiply(2, 3)           # Output: 6
puts extended_math_ops.multiply(2, 3)  # Output: 6, keeping backward compatibility
puts extended_math_ops.multiply(2, 3, 4)  # Output: 24
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal