How do you do polymorphism in Ruby?

后端 未结 8 1338
灰色年华
灰色年华 2021-01-01 21:40

In C#, I can do this:

class Program
{
    static void Main(string[] args)
    {
        List animals = new List();

        anima         


        
相关标签:
8条回答
  • 2021-01-01 22:25

    There's a method becomes which implements a polymorphism (by coping all instance variables from given class to new one)

    class Animal
      attr_reader :name
    
      def initialize(name = nil)
        @name = name
      end
    
      def make_noise
        ''
      end
    
      def becomes(klass)
        became = klass.new
        became.instance_variables.each do |instance_variable|
          value = self.instance_variable_get(instance_variable)
          became.instance_variable_set(instance_variable, value)
        end
    
        became
      end
    end
    
    class Dog < Animal
      def make_noise
        'Woof'
      end
    end
    
    class Cat < Animal
      def make_noise
        'Meow'
      end
    end
    
    animals = [Dog.new('Spot'), Cat.new('Tom')]
    
    animals.each do |animal|
      new_animal = animal.becomes(Cat)
      puts "#{animal.class} with name #{animal.name} becomes #{new_animal.class}"
      puts "and makes a noise: #{new_animal.make_noise}"
      puts '----'
    end
    

    and result is:

    Dog with name Spot becomes Cat
    and makes a noise: Meow
    ----
    Cat with name Tom becomes Cat
    and makes a noise: Meow
    ----
    
    • A polymorphism could be useful to avoid if statement (antiifcampaign.com)

    • If you use RubyOnRails becomes method is already implemented: becomes

    • Quicktip: if you mix polymorphism with STI it brings you the most efficient combo to refactor your code

    I wish it helped you

    0 讨论(0)
  • 2021-01-01 22:27

    A little variant of manveru's solution which dynamic create different kind of object based in an array of Class types. Not really different, just a little more clear.

    Species = [Dog, Cat]
    
    Species.each do |specie|
      animal = specie.new   # this will create a different specie on each call of new
      print animal.MakeNoise + "\n"
      animal.Sleep
    end
    
    0 讨论(0)
提交回复
热议问题