Полиморфизм состоит из слов греческого корня: polys (много) и morphe. (форма или форма), и это означает качество или состояние существования в различных формах или их принятия. В программировании это относится к возможности использовать одни и те же методы, но по-разному для разных объектов. Полиморфизм позволяет создавать более динамичные приложения.
Существует несколько способов использования полиморфизма:
Наследование:это одна из особенностей Ообъектно-ориентированного Оориентированного программирования(ООП). Полиморфизм дает нам возможность использовать один и тот же метод для разных объектов.
Чтобы достичь этого полиморфизма, вы должны создать подклассы из каждого отдельного вида животных. Каждый подкласс наследовал бы от суперкласса общий интерфейс. Благодаря наследованию подклассы теперь имеют общие методы из своего суперкласса. Делая это, он обеспечивает гибкость методов вашего суперкласса с точки зрения возможности повторного использования. Затем ваши подклассы зарезервированы для более подробного поведения и выходных данных.
class Animal def initialize(breed) @breed = breed end def make_some_noise puts "" end end class Cat < Animal def make_some_noise puts "Mew mew" end end class Dog < Animal def make_some_noise puts "Woof woof" end end class Duck < Animal def make_some_noise puts "Quackity quack" end end dog = Dog.new(dog) dog.make_some_noise # => Woof woof duck = Duck.new(duck) duck.make_some_noise # => Quackity quack
Хотя все наши животные относятся к разным типам: кошка, собака и утка, все они ведут себя одинаково — каждое из них может издавать звуки. Каждый тип просто возвращает другой результат. Здесь в дело вступает полиморфизм. Обратите внимание, что вы можете вызвать один и тот же метод для другого объекта, но он вернет другой результат. Метод make_some_noise внутри подклассов переопределяет метод суперкласса и выдает собственные настраиваемые выходные данные подклассов — полиморфизм позволяет этому методу быть более динамичным.
Вы также можете использовать модуль в этом случае, потому что классы имеют общее поведение. С модулем вы не можете создать объект. Модуль должен быть добавлен через «include» в класс. Включение позволяет классу и его объектам иметь одно и то же поведение, объявленное в модуле.
Duck Typing:
Помните, как удобен Ruby и что он динамичен… поэтому Ruby достаточно удобен тем, что вам не нужна иерархия классов объектов с общим интерфейсом, который был бы определенные супер и подклассы или наследование для зависимости кода. С помощью утиной печати вы можете еще больше абстрагироваться и разделить классы. В свою очередь, это делает ваше приложение еще более динамичным, поскольку уменьшает количество зависимостей кода и обеспечивает гибкость. Концепция утиной печати взята из следующей фразы:
Если он ходит, как утка, плавает, как утка, и крякает, как утка, Ruby достаточно счастлив, чтобы относиться к нему как к утке. Ruby не будет тратить время на размышления о том, действительно ли объект является уткой. При утиной типизации объект определяется возможностями — что он может делать, а не типом — что он из себя представляет. Методы внутри класса являются основной проблемой, и если их можно вызвать или нет, то не сам класс. Таким образом, даже если вещь не является настоящей уткой, Ruby будет рассматривать ее как утку.
Утиная типизация относится к тенденции Ruby меньше заботиться о классе объекта и больше заботиться о том, какие методы можно вызывать для него и какие операции можно над ним выполнять».
Вместо того чтобы проверять, относится ли объект к определенному типу, Ruby заботится только о том, может ли объект по-прежнему отвечать на вызов метода. Ruby позволит вам передать любой объект, отвечающий методу другого класса.
class Cat def make_some_noise puts "Mew mew" end end class Dog def make_some_noise puts "Woof woof" end end class Duck def make_some_noise puts "Quackity quack" end end class Animal def make_some_noise(animal) animal.make_some_noise end end animal = Animal.new animal.make_some_noise(Cat.new) #=> Meow mew animal.make_some_noise(Dog.new) #=> Woof woof animal.make_some_noise(Duck.new)#=> Quackity quack
Таким образом, приведенный выше код все равно будет работать даже с разделенным классом. Метод make_some_noise принимает в качестве переменной животное. Мы можем передать классу Animal любой объект, который отвечает на метод make_some_noise. Один раз мы передаем в метод объекты: Cat, Dog и Duck, даже если объекты из разных классов. Метод просто ведет себя по-разному и выводит по-разному в зависимости от объекта. Однако метод все равно работает — это полиморфизм!
Утиная типизация — это попытка перед покупкой системы тестирования. Если это работает, ура! Если нет, каааа — БУМ… он взорвется вам в лицо. Вы можете прочитать больше о недостатках и преимуществах использования утиной печати в моем следующем посте в блоге…
Если вам нужны дополнительные сведения о утиной типизации g или если вы хотите узнать о полиморфной ассоциации в рельсах.