Ruby面向对象编程Skill ruby-oop

Ruby 面向对象编程技能用于深入掌握Ruby语言的OOP核心特性,包括类定义、模块混入、继承、方法可见性等,适用于后端开发、软件架构设计和编程实践。关键词:Ruby, 面向对象编程, OOP, 类, 模块, 继承, 混入, 方法可见性, 后端开发, 软件设计。

后端开发 0 次安装 0 次浏览 更新于 3/25/2026

name: ruby-oop user-invocable: false description: 当处理Ruby的面向对象编程特性时使用,包括类、模块、继承、混入和方法可见性。 allowed-tools:

  • Bash
  • Read
  • Write
  • Edit

Ruby 面向对象编程

掌握Ruby优雅的面向对象编程特性。Ruby是一种纯面向对象语言,其中一切都是对象。

类定义

基本类结构

class Person
  # 类变量(在所有实例间共享)
  @@count = 0

  # 常量
  MAX_AGE = 150

  # 类方法
  def self.count
    @@count
  end

  # 构造函数
  def initialize(name, age)
    @name = name  # 实例变量
    @age = age
    @@count += 1
  end

  # 实例方法
  def introduce
    "Hi, I'm #{@name} and I'm #{@age} years old"
  end

  # 属性访问器(getter和setter)
  attr_accessor :name
  attr_reader :age      # 只读
  attr_writer :email    # 只写
end

person = Person.new("Alice", 30)
puts person.introduce
person.name = "Alicia"

方法可见性

class BankAccount
  def initialize(balance)
    @balance = balance
  end

  # 公共方法(默认)
  def deposit(amount)
    @balance += amount
    log_transaction(:deposit, amount)
  end

  def balance
    format_currency(@balance)
  end

  # 受保护方法 - 可由同一类或子类的实例调用
  protected

  def log_transaction(type, amount)
    puts "[#{type}] #{amount}"
  end

  # 私有方法 - 仅在此实例内可调用
  private

  def format_currency(amount)
    "$#{amount}"
  end
end

继承

单继承

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

  def speak
    "Some sound"
  end
end

class Dog < Animal
  def speak
    "Woof! My name is #{@name}"
  end

  # 使用super调用父类方法
  def introduce
    super  # 调用父类的speak方法
    puts "I'm a dog"
  end
end

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

方法重写和Super

class Vehicle
  def initialize(brand)
    @brand = brand
  end

  def start_engine
    puts "Engine starting..."
  end
end

class Car < Vehicle
  def initialize(brand, model)
    super(brand)  # 调用父类构造函数
    @model = model
  end

  def start_engine
    super  # 调用父类方法
    puts "#{@brand} #{@model} is ready to drive"
  end
end

模块和混入

模块作为命名空间

module MyApp
  module Utils
    def self.format_date(date)
      date.strftime("%Y-%m-%d")
    end
  end
end

MyApp::Utils.format_date(Time.now)

模块作为混入

module Swimmable
  def swim
    "I'm swimming!"
  end
end

module Flyable
  def fly
    "I'm flying!"
  end
end

class Duck
  include Swimmable  # 添加为实例方法
  include Flyable

  def quack
    "Quack!"
  end
end

duck = Duck.new
puts duck.swim
puts duck.fly

Extend vs Include

module Greetable
  def greet
    "Hello!"
  end
end

class Person
  include Greetable  # 添加为实例方法
end

class Company
  extend Greetable   # 添加为类方法
end

Person.new.greet    # 有效
Company.greet       # 有效

高级OOP模式

单例模式

class Database
  @instance = nil

  private_class_method :new

  def self.instance
    @instance ||= new
  end

  def connect
    puts "Connected to database"
  end
end

db1 = Database.instance
db2 = Database.instance
db1.object_id == db2.object_id  # true

方法缺失(动态方法)

class DynamicAttributes
  def method_missing(method_name, *args)
    attribute = method_name.to_s

    if attribute.end_with?("=")
      # Setter
      instance_variable_set("@#{attribute.chop}", args.first)
    else
      # Getter
      instance_variable_get("@#{attribute}")
    end
  end

  def respond_to_missing?(method_name, include_private = false)
    true
  end
end

obj = DynamicAttributes.new
obj.name = "Ruby"
puts obj.name  # "Ruby"

类实例变量

class Product
  @inventory = []

  class << self
    attr_accessor :inventory

    def add(product)
      @inventory << product
    end
  end
end

Product.add("Laptop")

Struct和OpenStruct

Struct(近似不可变)

Person = Struct.new(:name, :age) do
  def introduce
    "I'm #{name}, #{age} years old"
  end
end

person = Person.new("Bob", 25)
puts person.name
person.age = 26

OpenStruct(动态属性)

require 'ostruct'

person = OpenStruct.new
person.name = "Charlie"
person.age = 30
person.email = "charlie@example.com"

puts person.name

组合优于继承

class Engine
  def start
    "Engine started"
  end
end

class Wheels
  def rotate
    "Wheels rotating"
  end
end

class Car
  def initialize
    @engine = Engine.new
    @wheels = Wheels.new
  end

  def start
    @engine.start
  end

  def drive
    @wheels.rotate
  end
end

Comparable和Enumerable

使类可比较

class Person
  include Comparable

  attr_reader :age

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

  def <=>(other)
    age <=> other.age
  end
end

people = [Person.new("Alice", 30), Person.new("Bob", 25)]
puts people.sort.map(&:age)  # [25, 30]

类变量 vs 实例变量

class Counter
  @@count = 0      # 类变量(共享)
  @instances = []  # 类实例变量(不与子类共享)

  def initialize
    @@count += 1
  end

  def self.count
    @@count
  end
end

最佳实践

  1. 优先使用组合而非继承 处理复杂关系
  2. 使用模块进行混入 在不相关的类之间共享行为
  3. 保持类小而专注(单一职责原则)
  4. 使用attr_accessor/reader/writer 代替手动getter/setter
  5. 利用private/protected 封装实现细节
  6. 优先使用实例变量 而非类变量,以避免意外共享
  7. 使用Struct处理简单数据对象 而非完整类
  8. 重写to_s以进行调试 提供有意义的字符串表示

反模式

不要不必要地使用类变量 - 它们在继承层次结构中共享 ❌ 不要创建上帝对象 - 保持类专注且小 ❌ 不要暴露内部状态 - 使用方法而非直接实例变量访问 ❌ 不要过度使用继承 - 优先使用组合或模块 ❌ 不要忽略可见性修饰符 - 它们用于封装

相关技能

  • ruby-metaprogramming - 用于动态类/方法生成
  • ruby-blocks-procs-lambdas - 用于函数式编程模式
  • ruby-modules - 用于高级模块使用