ZetCode

Ruby super 关键字

最后修改日期:2025 年 4 月 27 日

本教程解释了如何在方法继承中使用 Ruby 的 super 关键字。super 关键字从子类调用父类方法。

super 关键字会调用父类中同名的方法。它对于方法覆盖同时保留父类行为至关重要。

super 可以带参数或不带参数使用。在不带括号调用时,它会自动转发参数。这使得继承更加灵活。

基本的 super 用法

此示例展示了 `super` 扩展父类方法的最简单用法。子类添加了行为,同时保留了父类的行为。

basic_super.rb
class Parent
  def greet
    puts "Hello from Parent"
  end
end

class Child < Parent
  def greet
    super
    puts "Hello from Child"
  end
end

Child.new.greet

super 调用会执行父类的 `greet` 方法。然后子类添加自己的消息。这种模式扩展了功能。

带参数的 super

在覆盖带参数的方法时,super 可以自动或显式地转发参数。此示例演示了这两种方法。

super_with_args.rb
class Calculator
  def add(x, y)
    x + y
  end
end

class ScientificCalculator < Calculator
  def add(x, y)
    result = super
    puts "Calculation result: #{result}"
    result
  end
end

puts ScientificCalculator.new.add(5, 3)

不带括号的 super 会转发所有参数。子类增强了方法,增加了日志记录,同时保留了原始计算。

带显式参数的 super

有时您需要修改参数,然后再将它们传递给父类。此示例演示了使用 super 进行显式参数传递。

super_explicit_args.rb
class Animal
  def initialize(name)
    @name = name
  end
  
  def speak
    "#{@name} makes a sound"
  end
end

class Dog < Animal
  def initialize(name, breed)
    super(name)
    @breed = breed
  end
  
  def speak
    "#{super} and barks loudly"
  end
end

dog = Dog.new("Rex", "Labrador")
puts dog.speak

子类仅将 `name` 传递给父类的 initialize。`speak` 方法结合了父类和子类的行为,使用了 super

没有父类方法的 super

当不存在父类方法时调用 super 会引发错误。此示例展示了如何安全地处理此类情况。

super_no_parent.rb
class Base
  # No method defined
end

class Derived < Base
  def example
    super rescue puts "Parent has no example method"
    puts "Child method continues"
  end
end

Derived.new.example

super 找不到父类方法时,`rescue` 子句会阻止程序崩溃。这种防御性编程可以处理边缘情况。

带模块的 super

super 可以与继承链中的模块一起使用。此示例展示了通过包含的模块进行方法查找。

super_with_modules.rb
module Auditable
  def save
    puts "Audit log created"
    super
  end
end

class Document
  def save
    puts "Document saved"
  end
end

class Invoice < Document
  include Auditable
end

Invoice.new.save

Auditable 中的 super 调用 Document 的 `save`。Ruby 的方法查找会找到下一个可用的实现。

带块的 super

接受块的方法可以使用 super 将块传递给父类。此示例演示了块的转发。

super_with_block.rb
class Generator
  def generate
    yield "Base value"
  end
end

class EnhancedGenerator < Generator
  def generate
    super do |value|
      yield "Enhanced #{value}"
    end
  end
end

EnhancedGenerator.new.generate { |v| puts "Received: #{v}" }

子类修改了块的输入,同时保留了父类的生成模式。super 无缝地处理了块。

单例方法中的 super

super 也可以在单例方法中使用。这个高级示例展示了单例方法的继承。

super_singleton.rb
class Person
  def name
    "John Doe"
  end
end

person = Person.new

def person.name
  "Mr. #{super}"
end

puts person.name

单例方法通过 super 调用原始实例方法。这种模式对于每个对象的自定义很有用。

来源

Ruby 类和模块文档

本教程通过示例介绍了 Ruby 的 super 关键字,展示了方法继承、参数处理和高级用法模式。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Ruby 教程