Ruby 为什么在继承中调用基类方法?

Ruby 为什么在继承中调用基类方法?,ruby,ruby-2.2,Ruby,Ruby 2.2,在基类的self.inherited方法中,传递子类,调用子类的name方法而调用基类方法。虽然如果在其他地方对同一类调用相同的方法,同样的事情也会发生 class A def self.name "a" end def self.inherited(subclass) puts B.hash puts B.name end end class B < A def self.name "b" end end puts B.hash puts B.nam

在基类的
self.inherited
方法中,传递子类,调用子类的
name
方法而调用基类方法。虽然如果在其他地方对同一类调用相同的方法,同样的事情也会发生

class A
 def self.name 
  "a"
 end

 def self.inherited(subclass)
  puts B.hash
  puts B.name
 end
end

class B < A
 def self.name 
  "b"
 end
end

puts B.hash
puts B.name
这里没有魔法

当您声明
B
时,事情发生的顺序如下(粗略地说):

  • B
    (类的一个实例)被创建(它继承了
    A
    的所有内容)。目前它没有任何具体内容

  • A.hook被调用

  • B
    类被打开并处理。只有在这一点上,它才能获得自己的属性和方法(除了那些可以在钩子中创建的属性和方法)

  • 因此,当(2)发生时,
    B
    唯一可用的
    名称是
    A
    中定义的名称

    这很容易使用以下代码进行检查:

    class A
      def self.name 
        "a"
      end
    
      def self.inherited(subclass)
        puts "B own methods, point 1: #{subclass.methods(false).join(', ')}"
      end
    end
    
    class B < A
      puts "B own methods, point 2: #{self.methods(false).join(', ')}"
    
      def self.name 
        "b"
      end
    
      puts "B own methods, point 3: #{self.methods(false).join(', ')}"
    end
    
    # B own methods, point 1: 
    # B own methods, point 2: 
    # B own methods, point 3: name
    
    A类
    def self.name
    “a”
    结束
    def self.inherited(子类)
    放置“B自己的方法,第1点:#{subclass.methods(false).join(',')}”
    结束
    结束
    B类

    现在一切都清楚了,对吗?

    继承的
    是在创建子类之前还是之后生效的?有趣的事实:在任何一种情况下,内置方法都会返回
    “B”
    (因为在使用
    关键字时,常量赋值发生在回调之前)。添加行
    放置“cat”
    紧跟在
    类B
    之后,查看它的显示时间。似乎需要post_继承方法,否则如果我必须按一些用户定义的值处理类,它会变得很麻烦。对于无法通过类(re)完成的虚构的
    post_继承的
    您想做什么打开和常见的Ruby习惯用法?@AnuragUniyal,这需要确定继承类的构造何时完成,这可能会有问题。此外,考虑到在构造子对象时,它可以修改父对象或创建兄弟对象。我不确定这样的行为对
    post\u继承的
    方法会有什么影响。我认为继承的主要原因是建立一个实例列表。@KonstantinStrukov可以用继承的而不是优雅的方法来完成,例如,如何对继承的
    {name=>subclass}
    @AnuragUniyal进行散列。你可以使用继承的
    来建立一个后代列表,然后根据需要建立散列。。。或者您可以使用与Rais对
    .substands
    方法相同的方法,该方法根本不使用挂钩(而是使用ObjectSpace)
    class A
      def self.name 
        "a"
      end
    
      def self.inherited(subclass)
        puts "B own methods, point 1: #{subclass.methods(false).join(', ')}"
      end
    end
    
    class B < A
      puts "B own methods, point 2: #{self.methods(false).join(', ')}"
    
      def self.name 
        "b"
      end
    
      puts "B own methods, point 3: #{self.methods(false).join(', ')}"
    end
    
    # B own methods, point 1: 
    # B own methods, point 2: 
    # B own methods, point 3: name