Ruby属性与方法 #

一、属性概述 #

属性是对象的状态,通过实例变量存储,通过方法访问。

二、attr系列方法 #

2.1 attr_reader #

ruby
class Person
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

person = Person.new("Ruby")
person.name
person.name = "Rails"

2.2 attr_writer #

ruby
class Person
  attr_writer :name

  def initialize(name)
    @name = name
  end

  def greet
    "Hello, #{@name}"
  end
end

person = Person.new("Ruby")
person.name = "Rails"
person.greet
person.name

2.3 attr_accessor #

ruby
class Person
  attr_accessor :name, :age

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

person = Person.new("Ruby", 30)
person.name
person.name = "Rails"
person.age
person.age = 31

2.4 手动实现 #

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

  def name
    @name
  end

  def name=(new_name)
    @name = new_name
  end
end

2.5 自定义访问器 #

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

  def name
    @name.upcase
  end

  def name=(new_name)
    @name = new_name.strip
  end
end

person = Person.new("  Ruby  ")
person.name
person.name = "  Rails  "
person.name

三、方法类型 #

3.1 实例方法 #

ruby
class Person
  def greet
    "Hello!"
  end
end

person = Person.new
person.greet

3.2 类方法 #

ruby
class Person
  def self.create
    Person.new
  end

  class << self
    def default
      Person.new
    end
  end
end

Person.create
Person.default

3.3 模块方法 #

ruby
module Helper
  def self.utility
    "Utility method"
  end

  module_function

  def exported
    "Exported method"
  end
end

Helper.utility
Helper.exported

四、访问控制 #

4.1 public #

ruby
class Person
  def greet
    "Hello!"
  end
end

person = Person.new
person.greet

4.2 private #

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

  def introduce
    "Hello, I'm #{name}"
  end

  private

  def name
    @name
  end
end

person = Person.new("Ruby")
person.introduce
person.name

4.3 protected #

ruby
class Person
  def initialize(age)
    @age = age
  end

  def older_than?(other)
    age > other.age
  end

  protected

  def age
    @age
  end
end

alice = Person.new(30)
bob = Person.new(25)
alice.older_than?(bob)
alice.age

4.4 设置访问控制 #

ruby
class Example
  def public_method
  end

  private :public_method

  def another_public
  end

  private

  def private_method_1
  end

  def private_method_2
  end

  public :another_public
end

4.5 访问控制对比 #

访问级别 类内部 子类 外部
public
protected
private

五、类变量与类实例变量 #

5.1 类变量 #

ruby
class Counter
  @@count = 0

  def initialize
    @@count += 1
  end

  def self.count
    @@count
  end
end

Counter.new
Counter.new
Counter.count

5.2 类实例变量 #

ruby
class Counter
  @count = 0

  def initialize
    self.class.count += 1
  end

  class << self
    attr_accessor :count
  end
end

Counter.count = 0
Counter.new
Counter.new
Counter.count

5.3 继承中的差异 #

ruby
class Parent
  @@class_var = "parent"
  @class_instance_var = "parent"
end

class Child < Parent
  @@class_var = "child"
  @class_instance_var = "child"
end

Parent.class_variable_get(:@@class_var)
Child.class_variable_get(:@@class_var)

Parent.instance_variable_get(:@class_instance_var)
Child.instance_variable_get(:@class_instance_var)

六、方法可见性最佳实践 #

6.1 最小暴露原则 #

ruby
class User
  def initialize(email, password)
    @email = email
    @password = encrypt(password)
  end

  def authenticate(password)
    @password == encrypt(password)
  end

  private

  def encrypt(text)
    Digest::SHA256.hexdigest(text)
  end
end

6.2 使用protected共享实现 #

ruby
class Employee
  def initialize(salary)
    @salary = salary
  end

  def higher_paid_than?(other)
    salary > other.salary
  end

  protected

  def salary
    @salary
  end
end

七、实用示例 #

7.1 配置类 #

ruby
class Configuration
  class << self
    attr_accessor :api_key, :timeout, :debug

    def configure
      yield self
    end

    def reset
      @api_key = nil
      @timeout = 30
      @debug = false
    end
  end

  reset
end

Configuration.configure do |config|
  config.api_key = "secret"
  config.timeout = 60
  config.debug = true
end

7.2 属性验证 #

ruby
class Person
  attr_reader :name, :age

  def name=(value)
    raise ArgumentError, "Name cannot be empty" if value.nil? || value.empty?
    @name = value
  end

  def age=(value)
    raise ArgumentError, "Age must be positive" if value.nil? || value < 0
    @age = value
  end
end

person = Person.new
person.name = "Ruby"
person.age = 30

7.3 虚拟属性 #

ruby
class Person
  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end

  def full_name
    "#{@first_name} #{@last_name}"
  end

  def full_name=(name)
    @first_name, @last_name = name.split(" ", 2)
  end
end

person = Person.new("Ruby", "Rails")
person.full_name
person.full_name = "New Name"
person.full_name

八、总结 #

本章我们学习了:

  1. attr系列方法:attr_reader、attr_writer、attr_accessor
  2. 方法类型:实例方法、类方法、模块方法
  3. 访问控制:public、private、protected
  4. 类变量:@@变量、类实例变量
  5. 最佳实践:最小暴露原则、属性验证

接下来让我们学习Ruby的继承!

最后更新:2026-03-27