【问题标题】:Crystal: inheritance vs inclusion vs extensionCrystal:继承 vs 包含 vs 扩展
【发布时间】:2023-03-09 11:25:02
【问题描述】:

我在In Crystal, what's the difference between inheritance and inclusion? 询问了这个问题的一个更有限的版本,但我认为我(和其他读者)会从更全面的答案中受益。

继承(使用<)、包含(使用include)和扩展(使用@ 987654324@) 在 Crystal 类中?

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

    回答

    类继承

    < 的继承会将继承的中的实例属性、实例方法、类属性和类方法复制到当前类中。

    模块不能继承或被继承。

    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 1.0.0 起有效

    【讨论】:

    • 我只是快速浏览了答案,但是“一个类型(模块或类)可以只扩展一个模块。”似乎不正确。可以进行多次扩展。
    • 从刚刚探索问题空间的人那里得到这样的解释真是太好了 =) 也许你可以帮助改进github.com/crystal-lang/crystal-book 的文档?那里的公关也会更容易解决细节。
    • @JohannesMüller 我从你的帖子中得到了“可以扩展一个模块”的部分!我误会了吗?也是的,我很乐意为那里的文档提供帮助,尽管我不确定这在语言参考中的位置。
    猜你喜欢
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2011-06-16
    • 1970-01-01
    • 2021-09-02
    • 2022-01-19
    相关资源
    最近更新 更多