简体   繁体   English

从 class 方法调用 super

[英]Calling super from a class method

When redefining a class method I want to be able to call super, just as I would in a instance method.在重新定义 class 方法时,我希望能够调用 super,就像在实例方法中一样。

For example, I have a class hi with a class method Hi.hi例如,我有一个 class hi 和一个 class 方法Hi.hi

class Hi
  def self.hi
    puts "hi"
  end
end

Hi.hi #=> "hi"

Now, Lets say i want to redefine self.hi现在,假设我想重新定义self.hi

class Hi
  def self.hi
    super
    puts "Oh!"
  end
end

Hi.hi #=> NoMethodError: super: no superclass method `hi' for Hi:Class

Why doesn't this work?为什么这不起作用?

I know I can get the same functionality using alias (as below), it just seems rather unnecessary.我知道我可以使用别名(如下所示)获得相同的功能,这似乎是不必要的。

class Hi
  class << self
    def new_hi
      old_hi
      puts "Oh!"
    end
    alias :old_hi :hi
    alias :hi :new_hi 
  end
end

Hi.hi #=> "hi\n Oh!"

Is there a better way to do this?有一个更好的方法吗?

Super works for child classes inherited from a parent class. Super 适用于从父 class 继承的子类。

In your case alias is the only way.在您的情况下,别名是唯一的方法。 Or you can use alias_method :或者您可以使用alias_method

alias_method :old_hi, :hi

def self.hi
  old_hi
  puts "Oh!"
end

In the context of your code "super" refers to the Object class, since Object doesn't have a "hi" class level method it fails. In the context of your code "super" refers to the Object class, since Object doesn't have a "hi" class level method it fails. "Hi" is an object of type "Class". “Hi”是“Class”类型的 object。

You don't have a super class defined so it defaults to object.您没有定义超级 class,因此它默认为 object。 You can see this at the console by typing "Hi.superclass"您可以通过键入“Hi.superclass”在控制台中看到这一点

The better way is to use traditional OOP to do this:更好的方法是使用传统的 OOP 来做到这一点:

class Hi
  def self.hi
    puts "hi"
  end
end

class Ho < Hi
  def self.hi
    super
    puts "Oh!"
  end
end

The "class << self" syntax ends up creating an invisible intermediate class which does the inheritance chain. “class << self”语法最终创建了一个不可见的中间 class,它执行 inheritance 链。

It shouldn't matter that you created a new class since the new class extends the old one, they are interchangeable, except for the different output of self.hi()您创建一个新的 class 并不重要,因为新的 class 扩展了旧的 class,它们是可以互换的,除了 self.hi() 的不同 output

It does not work.Because the ancestors for your class Hi don't have a method hi.它不起作用。因为您的 class 嗨的祖先没有方法嗨。

I don't understand your problem.我不明白你的问题。

If you really redefine self.hi (Saying: super has a hi), then it works:如果你真的重新定义 self.hi(说:super 有一个 hi),那么它可以工作:

class Hi_super
  def self.hi
    puts "Oh - super!"
  end
end


class Hi < Hi_super
  def self.hi
    super
    puts "Oh!"
  end
end

Hi.hi

Or in another version:或者在另一个版本中:

class Object
  def self.hi
    puts "Oh - super!"
  end
end


class Hi 
  def self.hi
    super
    puts "Oh!"
  end
end

Hi.hi

Both version s results in两个版本都导致

Oh - super!
Oh!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM