Skip to main content

OOP Polymorphism

Definition: "Poly" stands for "many" and "morph" stands for "forms". Generally, polymorphism means one name different uses. Technically, it means being able to send the same message to different objects and get different result.

Polymorphism through Inheritance
We can achieve polymorphism through inheritance. For example

class GenericParser
 def parse
   raise NotImplementedError, 'You must implement the parse method'
 end
end

class JsonParser < GenericParser
 def parse
   puts 'An instance of the JsonParser class received the parse message'
 end
end

class XmlParser < GenericParser
 def parse
   puts 'An instance of the XmlParser class received the parse message'
 end
end

Here the GenericParser is the base class. Class JsonParser and XmlParser are inherited from the GenericParser.

Now suppose we run the below code.

puts 'Using the XmlParser'
parser = XmlParser.new
parser.parse

puts 'Using the JsonParser'
parser = JsonParser.new
parser.parse

The output of the above code will be as following.

OUTPUT:
Using the XmlParser
An instance of the XmlParser class received the parse message

Using the JsonParser
An instance of the JsonParser class received the parse message

Here we can see that the same parse method behaves differently for other classes based upon it is called form which object.

               
OOP Polymorphism with DuckTyping
In Ruby, traditional methods of polymorphism (seen above and in languages such as Java) are not widely accepted. A concept known as "duck typing" is preferred.

class GenericParser
  def parse(parser)
    parser.parse
  end
end

class XmlParser
  def parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end

class JsonParser
  def parse
    puts 'An instance of the JsonParser class received the parse message'
  end
end

Here we do the same thing now without inheritance. We write the code as below.

parser = GenericParser.new
puts 'Using the XmlParser'
parser.parse(XmlParser.new)

puts 'Using the JsonParser'
parser.parse(JsonParser.new)
The output of the code is as below.

OUTPUT:

Using the XmlParser
An instance of the XmlParser class received the parse message

Using the JsonParser
An instance of the JsonParser class received the parse message

Here we can see that the same method parser.parse behaves differently on the basis of the which of object is passed as a parameter. It calls particular parse method on the basis of which type of object is passed.

Notice that the method behaves differently depending on the object that receives it’s message. This is polymorphism!

References:





Comments

Popular posts from this blog

Rails: Grouping the records by group_by method

Many times we come across such situations where we need to group records, like when we want to display grouped messages, email, alerts .etc based on date or time. Here is the simple code which provides a significant use of group_by method.
Controller Part

classMessagesController < ApplicationController
defindex
@message = Message.all

#Retrives all messages and divides into two groups todays messages and other messages
@grouped_messages = @message.group_by{ |t| t.created_at.to_date == DateTime.now.to_date }

List of Common mistakes in Ruby

Always use spaces around operators, after commas, colons and semicolons, around { and before }. White space might be (mostly) irrelevant to the Ruby interpreter, but its proper use is the key to writing easily readable code. Also it makes the design more readable and code much cleaner.
product = 1 * 2 array = [1, 2, 3, 4, 5] array.map { |a| a + 2 }

There should be no spaces after (, [ or before ], ) these brackets.
['ankur', 'vyas'] sum(a, b)
Also don't use spaces in while providing the range.
Use5..9 over 5 .. 9Use'a'..'z' over 'a' .. 'z'
When using switch case statements use the following indentation.
casewhen input = '+'puts'The operation is addition'when'-'puts'The operation is subtraction'when'*'puts'The operation is multiplication'elseputs'The operation is division'end
Use following indentation if the parameters exceeds to more than one line.
defsend_mail(source) Mailer.deliver(…