如何解决Crystal:继承 vs 包含 vs 扩展 类继承模块包含模块扩展
我在 In Crystal,what's the difference between inheritance and inclusion? 提出了这个问题的更有限版本,但我认为我(和其他读者)会从更全面的答案中受益。
继承(带有<
)、包含(带有include
)和扩展之间有什么区别>(使用 extend
)在 Crystal 类中?
解决方法
答案
类继承
带有 <
的继承将实例属性、实例方法、类属性和类方法从继承的类复制到当前类中。
模块不能继承或被继承。
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"
注意@@stuff
模块定义中的Talkative
指的是扩展类的class属性,而不是Talkative
本身的class属性.
无法扩展定义实例方法的模块。这会导致编译错误。
一个类型(模块或类)只能扩展一个模块。
参考文献
此信息基于:
- Crystal Reference: Classes and Methods
- Crystal Reference: Modules
- Answer to my previous question by Johannes Müller
- 来自
crystal-lang/crystal
Gitter 聊天室用户的帮助。
此答案自 Crystal 1.0.0 起有效
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。