Ruby继承 #

一、继承概述 #

Ruby支持单继承,一个类只能有一个直接父类。继承允许子类获得父类的属性和方法。

二、基本继承 #

2.1 定义子类 #

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

  def speak
    "Some sound"
  end
end

class Dog < Animal
end

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

2.2 继承链 #

ruby
class Animal
end

class Mammal < Animal
end

class Dog < Mammal
end

Dog.superclass
Dog.superclass.superclass
Dog.ancestors

2.3 is_a? 和 kind_of? #

ruby
class Animal
end

class Dog < Animal
end

dog = Dog.new

dog.is_a?(Dog)
dog.is_a?(Animal)
dog.is_a?(Object)
dog.kind_of?(Dog)

三、方法重写 #

3.1 重写方法 #

ruby
class Animal
  def speak
    "Some sound"
  end
end

class Dog < Animal
  def speak
    "Woof!"
  end
end

class Cat < Animal
  def speak
    "Meow!"
  end
end

Dog.new.speak
Cat.new.speak

3.2 super关键字 #

ruby
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} - Woof!"
  end
end

dog = Dog.new("Buddy", "Golden Retriever")
dog.speak

3.3 super参数 #

ruby
class Parent
  def method(a, b)
    puts "Parent: a=#{a}, b=#{b}"
  end
end

class Child < Parent
  def method(a, b)
    super
    super(a, b)
    super(a)
  end
end

四、方法查找 #

4.1 方法查找顺序 #

ruby
class Animal
  def move
    "Animal moves"
  end
end

class Mammal < Animal
  def move
    "Mammal moves"
  end
end

class Dog < Mammal
end

Dog.new.move

class Dog < Mammal
  def move
    "Dog moves"
  end
end

Dog.new.move

4.2 method_missing #

ruby
class Dynamic
  def method_missing(name, *args)
    if name.to_s.start_with?("find_by_")
      attribute = name.to_s.sub("find_by_", "")
      find_by(attribute, args.first)
    else
      super
    end
  end

  def respond_to_missing?(name, include_private = false)
    name.to_s.start_with?("find_by_") || super
  end

  private

  def find_by(attribute, value)
    puts "Finding by #{attribute}: #{value}"
  end
end

obj = Dynamic.new
obj.find_by_name("Ruby")
obj.respond_to?(:find_by_name)

五、继承与初始化 #

5.1 自动继承initialize #

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

class Dog < Animal
end

dog = Dog.new("Buddy")

5.2 重写initialize #

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

class Dog < Animal
  def initialize(name, breed)
    super(name)
    @breed = breed
  end
end

dog = Dog.new("Buddy", "Golden Retriever")

六、抽象类 #

6.1 模拟抽象类 #

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

  def speak
    raise NotImplementedError, "Subclasses must implement speak"
  end
end

class Dog < Animal
  def speak
    "Woof!"
  end
end

Animal.new("Test").speak
Dog.new("Buddy").speak

6.2 模块作为接口 #

ruby
module Speakable
  def speak
    raise NotImplementedError
  end
end

class Dog
  include Speakable

  def speak
    "Woof!"
  end
end

七、实用示例 #

7.1 形状层次结构 #

ruby
class Shape
  def initialize(color)
    @color = color
  end

  def area
    raise NotImplementedError
  end

  def perimeter
    raise NotImplementedError
  end

  def info
    "Color: #{@color}, Area: #{area}, Perimeter: #{perimeter}"
  end
end

class Rectangle < Shape
  def initialize(color, width, height)
    super(color)
    @width = width
    @height = height
  end

  def area
    @width * @height
  end

  def perimeter
    2 * (@width + @height)
  end
end

class Circle < Shape
  def initialize(color, radius)
    super(color)
    @radius = radius
  end

  def area
    Math::PI * @radius ** 2
  end

  def perimeter
    2 * Math::PI * @radius
  end
end

rect = Rectangle.new("red", 5, 3)
circle = Circle.new("blue", 2)

rect.info
circle.info

7.2 员工层次结构 #

ruby
class Employee
  attr_reader :name, :id

  def initialize(name, id)
    @name = name
    @id = id
  end

  def calculate_pay
    raise NotImplementedError
  end

  def to_s
    "#{name} (#{id})"
  end
end

class SalariedEmployee < Employee
  def initialize(name, id, salary)
    super(name, id)
    @salary = salary
  end

  def calculate_pay
    @salary
  end
end

class HourlyEmployee < Employee
  def initialize(name, id, rate, hours)
    super(name, id)
    @rate = rate
    @hours = hours
  end

  def calculate_pay
    @rate * @hours
  end
end

salaried = SalariedEmployee.new("Alice", 1, 5000)
hourly = HourlyEmployee.new("Bob", 2, 50, 160)

salaried.calculate_pay
hourly.calculate_pay

7.3 ActiveRecord风格继承 #

ruby
class BaseModel
  def self.find(id)
    data = database_find(id)
    new(data) if data
  end

  def self.all
    database_all.map { |data| new(data) }
  end

  def initialize(attributes = {})
    attributes.each do |key, value|
      instance_variable_set("@#{key}", value)
    end
  end

  def save
    valid? && persist
  end

  def valid?
    true
  end

  private

  def persist
    raise NotImplementedError
  end

  def self.database_find(id)
  end

  def self.database_all
    []
  end
end

八、继承最佳实践 #

8.1 组合优于继承 #

ruby
class Engine
  def start
    "Engine started"
  end
end

class Car
  def initialize
    @engine = Engine.new
  end

  def start
    @engine.start
  end
end

8.2 避免深层继承 #

ruby
class Animal
end

class Mammal < Animal
end

class Carnivore < Mammal
end

class Dog < Carnivore
end

class Animal
end

class Dog < Animal
  include Carnivore
  include Mammal
end

九、总结 #

本章我们学习了:

  1. 基本继承:< 操作符、继承链
  2. 方法重写:重写、super关键字
  3. 方法查找:查找顺序、method_missing
  4. 抽象类:NotImplementedError、模块接口
  5. 最佳实践:组合优于继承、避免深层继承

接下来让我们学习Ruby的模块与Mixin!

最后更新:2026-03-27