【问题标题】:Calling method in parent class from subclass methods in Ruby从Ruby中的子类方法调用父类中的方法
【发布时间】:2013-08-26 16:37:19
【问题描述】:

我已经使用super 来初始化父类,但我看不到任何从子类方法调用父类的方式。

我知道 PHP 和其他语言确实具有此功能,但在 Ruby 中找不到实现此功能的好方法。

在这种情况下人们会怎么做?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    如果方法名称相同,即您要覆盖一个方法,您可以简单地使用super。否则,您可以使用 alias_method 或绑定。

    class Parent
      def method
      end
    end
    
    class Child < Parent
      alias_method :parent_method, :method
      def method
        super
      end
    
      def other_method
        parent_method
        #OR
        Parent.instance_method(:method).bind(self).call
      end
    end
    

    【讨论】:

    • 这不起作用。 Child.new.other_method 返回NoMethodError: super: no superclass method 'other_method' for #&lt;Child:0x007fca161a9400&gt;。对super.method() 的调用只会在调用super 返回的任何内容上调用method(在这种情况下,它不存在)。 super 不是对实例的 superclass 的引用。
    • 同时调用super 将使用传递给子方法的确切参数调用 super。如果你想指定参数,你可以通过调用 super 来指定它们:EG:def child(a, b); super; end vs def child(a, b); super(somevar); end
    【解决方案2】:

    super keyword调用超类中的同名方法:

    class Foo
      def foo
        "#{self.class}#foo"
      end
    end
    
    class Bar < Foo
      def foo
        "Super says: #{super}"
      end
    end
    
    Foo.new.foo # => "Foo#foo"
    Bar.new.foo # => "Super says: Bar#foo"
    

    【讨论】:

      【解决方案3】:

      Ruby 中的super 关键字实际上调用了父类中的同名方法。 (source)

      class Foo
        def foo
          # Do something
        end
      end
      
      class Bar < Foo
        def foo
          super # Calls foo() method in parent class
        end
      end
      

      【讨论】:

      • 如果请求者明确提到 PHP 作为他知道的其他语言...
      • 这个答案对我很有帮助,他说他知道 PHP 和其他语言都有这个功能(不是他只知道 PHP)。
      【解决方案4】:

      其他人已经说得很好。还有一点需要注意:

      不支持在超类中调用 foo 方法的语法 super.foo。相反,它将调用super-方法并在返回的结果上尝试调用foo

        class A
          def a
            "A::a"
          end
        end
      
        class B < A
          def a
            "B::a is calling #{super.a}" # -> undefined method `a` for StringClass 
          end
        end
      

      【讨论】:

      • 这是人们应该注意的一个重要区别,因此感谢您指出这一点!
      【解决方案5】:
      class Parent
        def self.parent_method
          "#{self} called parent method"
        end
      
        def parent_method
          "#{self} called parent method"
        end
      end
      
      class Child < Parent
      
        def parent_method
          # call parent_method as
          Parent.parent_method                # self.parent_method gets invoked
          # call parent_method as
          self.class.superclass.parent_method # self.parent_method gets invoked
          super                               # parent_method gets invoked 
          "#{self} called parent method"      # returns "#<Child:0x00556c435773f8> called parent method"
        end
      
      end
      
      Child.new.parent_method  #This will produce following output
      Parent called parent method
      Parent called parent method
      #<Child:0x00556c435773f8> called parent method
      #=> "#<Child:0x00556c435773f8> called parent method"
      

      self.class.superclass == Parent #=&gt; true

      Parent.parent_methodself.class.superclass 将调用 Parentself.parent_method(类方法) 而 super调用Parentparent_method(实例方法)。

      【讨论】:

        猜你喜欢
        • 2023-03-21
        • 2016-02-14
        • 2020-01-14
        • 1970-01-01
        • 2017-11-09
        • 2014-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多