I believe this is a general OOP question, but I'm using Crystal insofar as that matters.
What is the right way to handle a situation where I have child classes that need to share a type but that type isn't the parent. For example, let's say I have animals: cats and dogs, and I also have baby animals: kittens and puppies. I want the kittens and puppies to be their own type with their own set of "parent" methods.
class Animal
end
class Dog < Animal
end
class Cat < Animal
end
class Puppy < Dog
property? needs_milk = true
end
class Kitten < Cat
property? needs_milk = true
end
I know that if all I needed was some properties or methods I could do this via a mixin:
module BabyAnimal
property? needs_milk = true
end
but for my actual use case, I want to guarantee that all members of an array "are" BabyAnimals (and thus have baby animal methods and properties) i.e.
[] of Kitten | Puppy
So it feels like inheritance is the only / right way to do this.
Or am I missing something?
Modules are part of the type hierarchy. If you use the type restriction BabyAnimal
, you can be assured that it only matches types that include that module.
Kitten.new.is_a?(BabyAnimal) # => true
array = [] of BabyAnimal
array << Kitten.new
array << Puppy.new