【发布时间】:2023-03-09 11:25:02
【问题描述】:
我在In Crystal, what's the difference between inheritance and inclusion? 询问了这个问题的一个更有限的版本,但我认为我(和其他读者)会从更全面的答案中受益。
继承(使用<)、包含(使用include)和扩展(使用@ 987654324@) 在 Crystal 类中?
【问题讨论】:
标签: crystal-lang
我在In Crystal, what's the difference between inheritance and inclusion? 询问了这个问题的一个更有限的版本,但我认为我(和其他读者)会从更全面的答案中受益。
继承(使用<)、包含(使用include)和扩展(使用@ 987654324@) 在 Crystal 类中?
【问题讨论】:
标签: crystal-lang
< 的继承会将继承的类中的实例属性、实例方法、类属性和类方法复制到当前类中。
模块不能继承或被继承。
class A
# Equivalent to `@@foo = 1` with corresponding getter and setter class methods
@@foo = 1
# Equivalent to `@foo = ` with corresponding getter and setter instance methods
@foo = 2
end
class B < A
end
pp A.foo == B.foo # true
pp A.new.foo == B.new.foo # true
超类中类属性的值与子类中的值不同,但类型相同。
class C
class_property foo = 1
end
class D < C
end
D.foo = 9
pp C.foo == D.foo # false
一个类只能从一个类继承。
include 将包含的模块中的实例属性和实例方法复制到当前类或模块中。
不能包含类。
可以在模块上定义类属性和类方法,但是这些不能被包含重复;他们被忽略了。
module BirdHolder
# Ignored by `include`
class_property bird = "123"
property bird = "456"
end
class Thing
include BirdHolder
end
pp Thing.new.bird # "456"
pp Thing.bird # Error: undefined method 'bird' for Thing1.class
一个类型(模块或类)可以包含任意数量的模块。
extend 将包含的模块中的实例方法复制到当前类或模块中,但作为类方法。
类不能扩展。
扩展模块中的类属性和类方法被忽略。
module Talkative
# Ignored by `extend`
@@stuff = "zxcv"
# Ignored by `extend`
def self.say_stuff
puts "stuff"
end
def say_stuff
puts @@stuff
end
end
class Thing
extend Talkative
@@stuff = "asdf"
end
Thing.say_stuff # "asdf"
注意Talkative模块定义中的@@stuff是指扩展类的类属性,而不是Talkative本身的类属性。
无法扩展定义实例方法的模块。这会导致编译错误。
一种类型(模块或类)只能扩展一个模块。
此信息基于:
crystal-lang/crystal Gitter 聊天室中用户的帮助。此答案自 Crystal 1.0.0 起有效
【讨论】: