Polymorphism in Ruby

Polymorphism comes form the greek words ‘polys’ meaning much or many and ‘morphe’ meaning form or shape. In programming, it refers to the ability to use functions or methods in different ways for different objects or data types.

Having the ability to use the same method in a different way depending on data input is very useful in Ruby. It greatly decreases the need for long, ugly if statements like this:

class Person
    def initialize(first, last, age)
         @first_name = first
         @last_name = last
         @age = age
    end

    def birthday
         @age += 1
    end

    def introduce(type)
         if type == "Student"
             puts "Hello teacher. My name is #{@first_name} #{@last_name}."
         elsif type == "Teacher"
             puts "Hello class. My name is #{@first_name} #{@last_name}."
         elsif type == "Parent"
             puts "Hi. I'm one of the parents. My name is #{@first_name} #{@last_name}."
         else
             puts "Hi everyone. My name is #{@first_name} #{@last_name}."
    end
end

john = Person.new("John", "Doe", 18)
john.introduce("Student")   #=> Hello teacher. My name is John Doe.

Now with polymorphism we are going to eliminate this ugly if statement by creating multiple classes that all have the introduce method. We are just going to change what the introduce method does for each class.

Example 1: Polymorphism with inheritance

All of our different types of people, i.e., students, parents, and teachers, are persons and they share similarities like names and birthdays. We don’t want to eliminate the Person class or the common methods. We are going to add class for each type of person that will inherit the person class. Then our new classes will inherit the common methods from Person, but will have a customized introduce method.

class Person
    def initialize(first, last, age)
         @first_name = first
         @last_name = last
         @age = age
    end

    def birthday
         @age += 1
    end

    def introduce
          puts "Hi everyone. My name is #{@first_name} #{@last_name}."
    end
end

class Student < Person
    def introduce
          puts "Hello teacher. My name is #{@first_name} #{@last_name}."
    end
end

class Teacher < Person
    def introduce
          puts "Hello class. My name is #{@first_name} #{@last_name}."
    end
end

class Parent < Person     
    def introduce           
        puts "Hi. I'm one of the parents. My name is #{@first_name} #{@last_name}."     
    end 
end 

john = Student.new("John", "Doe", 18) 
john.introduce   #=> Hello teacher. My name is John Doe.

Example 2: Polymorphism on different objects

The above example is easy to understand, but at least for me, this doesn’t really show us why polymorphism is so useful. Here is a more practical example. Our user is going to select an option from a list of possible actions relating to a Student. We won’t be able to predict which action the user will call so we send the same method to whichever object he/she picks.

class Student
    attr_accessor :first_name, :last_name, :age
def initialize(first, last, age)
@first_name = first
@last_name = last
@age = age
end

def birthday
@age += 1
end
end

class ViewStudent
def initialize(student)
@student = student
end

def do_something
puts "Student name: #{@student.first_name} #{@student.last_name}"
end
end

class UpdateStudent
def initialize(student)
@student = student
end

def do_something
puts "What is the student's first name?"
@student.first_name = gets.chomp
puts "What is the student's last name?"
@student.last_name = gets.chomp
puts "Updated student: #{@student.first_name} #{@student.last_name}"
end
end

choices = [ViewStudent, UpdateStudent]

student = Student.new("John", "Doe", 18)

puts "Select 1 to view student or 2 to update student."
selection = gets.chomp.to_i
obj = choices[selection - 1]
obj = obj.new(student)
obj.do_something

Have fun with polymorphism!

Leave a Reply

Your email address will not be published. Required fields are marked *