如何用子类重写的类方法初始化Ruby类属性?
解决Ruby子类重写类方法初始化类属性的问题
你的问题核心在于:父类A在定义时就直接执行了self.query = self.generate_query,这时候self指向的是A本身,所以query被初始化为父类方法的返回值。而子类B继承A时,默认会继承这个已经初始化好的query值,但不会自动调用子类重写的generate_query来更新它。
要实现每个类(包括父类和子类)都用自己的generate_query方法初始化query属性,最优雅的方式是利用Ruby的inherited钩子方法,它会在子类继承当前类时自动触发,我们可以在这个钩子里面为子类初始化专属的query值。
修改后的完整代码
class A class_attribute :query # 当子类继承A时触发这个钩子 def self.inherited(subclass) super # 调用父类的inherited实现(如果有的话) # 用子类自己的generate_query初始化它的query属性 subclass.query = subclass.generate_query end def self.generate_query "abcd" end # 初始化父类A自己的query self.query = generate_query end class B < A def self.generate_query query_part_1 = "ab" query_part_1 + generate_query_part_2 end def self.generate_query_part_2 "ef" # 注意:原代码中的`part_2`未定义,这里替换为实际字符串 end end
代码解释
inherited钩子:这个方法会在B继承A时被调用,参数subclass就是B类本身。我们在这里调用subclass.generate_query,也就是子类重写后的方法,来初始化子类的query属性。- 父类自身初始化:在
A类的最后,我们手动调用self.query = generate_query来初始化父类自己的query值。 - 子类方法重写:子类
B重写generate_query后,钩子会自动用这个方法的返回值设置B的query,不需要子类再额外写初始化代码。
验证结果
puts A.query # 输出 "abcd" puts B.query # 输出 "abef"
这样就实现了每个类的query都是由自身的generate_query方法生成的常量字符串啦。
内容的提问来源于stack exchange,提问作者Ashu Pachauri
相关产品推荐
相关产品推荐

