Ruby 继承

在面向对象编程中,继承允许一个类重用另一个类的代码。

例如,如果你有一个 Animal 类,那么 Dog 类可以继承它的行为(因为狗是动物的一种)。

class Animal
  def speak
    puts "I'm an animal"
  end
end

# Create Dog class that inherits from Animal
class Dog < Animal
end

Dog.new.speak  

# Output: I'm an animal

这意味着 Dog 类会自动从 Animal 类中获得 speak 方法。


Ruby 继承语法

在 Ruby 中,继承使用 < 符号来实现。

class ChildClass < ParentClass
end

这告诉 Ruby,一个类(子类)继承自另一个类(父类)。例如,

class Dog < Animal
end

这里,

  • Dog 是子类。
  • Animal 是父类(或超类)。
  • 这意味着 Dog 继承了父类所有方法的访问权限,以及那些方法初始化的实例变量。

访问父类方法和实例变量

假设 Animal 类有一个实例变量 @name(通过构造函数设置)和一个 speak 方法,该方法使用该变量打印一条消息。

我们来看看 Dog 子类如何继承这个实例变量和方法。

class Animal
  def initialize(name)
    @name = name
  end

  def speak
    puts "#{@name} makes a sound"
  end
end

class Dog < Animal
end

dog = Dog.new("Tommy")
dog.speak

输出

Tommy makes a sound

在这个例子中,Dog 类继承自 Animal,但没有添加自己的任何新代码。

然而,当我们创建一个 Dog 对象并调用 speak 方法时,它会在 speak 执行之前自动使用 initialize 方法来设置 @name

正如你所见,这两个方法都定义在父类中。

这表明 Dog 完全继承了 Animal 的行为和数据,即使没有重新定义任何内容。


添加子类特有的行为

继承不仅允许子类重用其父类的代码,还允许子类添加自己的新行为。

让我们在之前的例子基础上,为 Dog 类添加一个 wag_tail 方法。

class Animal
  def initialize(name)
    @name = name
  end

  def speak
    puts "#{@name} makes a sound"
  end
end

class Dog < Animal
  def wag_tail
    puts "#{@name} is wagging its tail"
  end
end

dog = Dog.new("Tommy")
dog.speak      
dog.wag_tail

输出

Tommy makes a sound
Tommy is wagging its tail

在这里,Dog 类仍然从 Animal 类继承 initializespeak 方法。但它也定义了自己的方法 wag_tail


重写父类方法

有时,你可能希望子类改变继承方法的行为方式。

在 Ruby 中,你可以通过在子类中重新定义该方法来实现,这被称为 **方法重写**。

让我们以之前讨论的 Animal 类为例,并在其子类中重写其中一个方法。

class Animal
  def initialize(name)
    @name = name
  end

  def speak
    puts "#{@name} makes a sound"
  end
end

class Dog < Animal
  # Override the speak method
  def speak
    puts "#{@name} says Woof!"
  end
end

dog = Dog.new("Tommy")
dog.speak  

# Output: Tommy says Woof!

在这里,Dog 类重写了 Animal 中的 speak 方法。

Dog 中重写的方法将通用消息替换为更具体的消息:“Tommy says Woof!”。


常见问题

重写父类方法后,是否可以包含父类方法的原始行为?

是的,可以。在 Ruby 中,你可以在子类方法中使用 super 关键字来调用父类中的原始版本。

这允许你扩展父类的行为,而不是完全替换它。例如,

class Animal
  def initialize(name)
    @name = name
  end

  def speak
    puts "#{@name} makes a sound"
  end
end

class Dog < Animal
  def speak
    super
    puts "#{@name} barks happily!"
  end
end

dog = Dog.new("Tommy")
dog.speak

# Output: 
# Tommy makes a sound
# Tommy barks happily!

使用 super 关键字,你可以建立在父类已有的功能之上。


Ruby 的单一继承模型

Ruby 只支持单一继承,这意味着一个类一次只能继承自一个父类。

允许:从一个类继承

class A
end

class B < A
end

在这里,B 类继承自 A 类。这在 Ruby 中是允许的,并且可以完美运行。

不允许:从多个类继承

class A
end

class B
end

# This will raise an error in Ruby
class C < A, B
end

Ruby 不支持多重继承,你不能直接从多个类继承。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战