我相信这是一个普遍的OOP问题,但是我在使用Crystal这个问题很重要.
处理我有子类需要共享类型但该类型不是父类的情况的正确方法是什么.例如,假设我有动物:猫和狗,我也有小动物:小猫和小狗.我想小猫和小狗是他们自己的类型与他们自己的"父"方法.
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
Run Code Online (Sandbox Code Playgroud)
我知道如果我需要的只是一些属性或方法,我可以通过mixin来做到这一点:
module BabyAnimal
property? needs_milk = true
end
Run Code Online (Sandbox Code Playgroud)
但对于我的实际用例,我想保证数组的所有成员"都是"BabyAnimals(因此有婴儿动物的方法和属性),即
[] of Kitten | Puppy
Run Code Online (Sandbox Code Playgroud)
所以感觉继承是唯一/正确的方法.
或者我错过了什么?
模块是类型层次结构的一部分.如果使用类型限制BabyAnimal,则可以确保它仅匹配包含该模块的类型.
Kitten.new.is_a?(BabyAnimal) # => true
array = [] of BabyAnimal
array << Kitten.new
array << Puppy.new
Run Code Online (Sandbox Code Playgroud)