Зміст дописунатисність на посилання, щоб перейти до потрібного місця
В Ruby, як і в багатьох інших об'єктно-орієнтованих мовах програмування, наслідування - це механізм, за допомогою якого клас може успадковувати властивості та методи іншого класу. Клас, який успадковує, називається підкласом, а клас, від якого успадковується, - батьківським класом.
Приклад поганого наслідування в Ruby
class Animal def speak puts "Animal speaks" end end class Dog < Animal def speak puts "Dog barks" end end class Cat < Animal # Цей клас не визначає свій власний метод speak end
У цьому прикладі клас Dog успадковує клас Animal, але клас Cat не надає свою власну реалізацію методу speak. Якщо ви спробуєте створити екземпляр класу Cat і викликати метод speak, він використовуватиме реалізацію з класу Animal. Це може бути проблемою, оскільки для кота більше властива відповідь - meow.
Тобто ми очікуємо отримати текст 'Cat meows', а отримаємо 'Animal speaks'. Здається що це не дуже критично, але в класах, які відповідають за бізнес логіку це може привести до більших проблем.
Ми можемо зробити наступне:
class Cat < Animal def speak puts "Cat meows" end end
Це наче вирішує проблему. Але уявіть що класів і методів десятки або сотні. Цей підхід не є best practice.
Приклад гарного наслідування в Ruby
class Shape def initialize(color) @color = color end def draw puts "Drawing a #{@color} shape" end end class Circle < Shape def initialize(color, radius) super(color) @radius = radius end def draw puts "Drawing a #{@color} circle with radius #{@radius}" end end class Square < Shape def initialize(color, side_length) super(color) @side_length = side_length end def draw puts "Drawing a #{@color} square with side length #{@side_length}" end end
У цьому прикладі є клас Shape, який є базовим класом для всіх геометричних фігур. Клас має атрибут color та метод draw, який виводить повідомлення про малювання.
Класи Circle та Square успадковують клас Shape і надають власні атрибути (radius та side_length) та реалізацію методу draw. Кожен клас може викликати метод draw, але з власним контекстом та даними.
Цей підхід дозволяє створювати загальні властивості та методи в базовому класі, а потім розширювати їх у підкласах, забезпечуючи власну унікальну логіку. Це робить код більш читабельним, підтримуваним та гнучким.