Crystal:继承 vs 包含 vs 扩展
Crystal: inheritance vs inclusion vs extension
我在 问了这个问题的更有限的版本,但我认为我(和其他读者)会从更全面的答案中受益。
继承(with<
)、inclusion(withinclude
)有什么区别, extension (with extend
) in Crystal 类?
回答
Class继承
继承 <
从继承的 class[=76= 复制实例属性、实例方法、class 属性和 class 方法] 到当前 class.
模块不能继承或被继承。
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
superclass 中 class 属性的值与 subclass 中的值不同,但类型相同。
class C
class_property foo = 1
end
class D < C
end
D.foo = 9
pp C.foo == D.foo # false
一个class可以继承自一个class。
模块包含
include
将包含的 模块 中的实例属性和实例方法复制到当前的 class 或模块中。
Class无法包含。
可以在模块上定义 class 属性和 class 方法,但是这些 不是 通过包含复制的;他们被忽略了。
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
一种类型(模块或 class)可以包含任意数量的模块。
模块扩展
extend
将包含的 模块 中的实例方法复制到当前 class 或模块中,但作为 class 方法。
Class无法扩展。
来自扩展模块的 Class 属性和 class 方法被忽略。
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
指的是扩展class的class属性,而不是 Talkative
本身的 class 属性。
无法扩展定义实例方法的模块。这会导致编译错误。
一种类型(模块或class)只能扩展一个模块。
参考资料
此信息基于:
- Crystal Reference: Classes and Methods
- Crystal Reference: Modules
- 来自
crystal-lang/crystal
Gitter 聊天室用户的帮助。
此答案自 Crystal 1.0.0
起有效
我在
继承(with<
)、inclusion(withinclude
)有什么区别, extension (with extend
) in Crystal 类?
回答
Class继承
继承 <
从继承的 class[=76= 复制实例属性、实例方法、class 属性和 class 方法] 到当前 class.
模块不能继承或被继承。
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
superclass 中 class 属性的值与 subclass 中的值不同,但类型相同。
class C
class_property foo = 1
end
class D < C
end
D.foo = 9
pp C.foo == D.foo # false
一个class可以继承自一个class。
模块包含
include
将包含的 模块 中的实例属性和实例方法复制到当前的 class 或模块中。
Class无法包含。
可以在模块上定义 class 属性和 class 方法,但是这些 不是 通过包含复制的;他们被忽略了。
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
一种类型(模块或 class)可以包含任意数量的模块。
模块扩展
extend
将包含的 模块 中的实例方法复制到当前 class 或模块中,但作为 class 方法。
Class无法扩展。
来自扩展模块的Class 属性和 class 方法被忽略。
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
指的是扩展class的class属性,而不是 Talkative
本身的 class 属性。
无法扩展定义实例方法的模块。这会导致编译错误。
一种类型(模块或class)只能扩展一个模块。
参考资料
此信息基于:
- Crystal Reference: Classes and Methods
- Crystal Reference: Modules
- 来自
crystal-lang/crystal
Gitter 聊天室用户的帮助。
此答案自 Crystal 1.0.0
起有效