#

Ruby 中类就是一种特殊的模块,定义一个类实际就是执行一个模块。

创建类 #

class Person
end

新建类的实例

person = Person.new

成员变量 #

Ruby 中使用 @ 作为前缀使用成员变量,在使用前无需预先定义,未初始化的实例变量的值为 nil,默认情况下成员变量只能用于在一个类的实例中的不同方法中共享数据

class Person
  def say(message)
    prefix = 'echo'
    @message = "#{prefix} #{message}"
  end
end

Setter 与 Getter #

Ruby 在类中方法外使用 attr_reader 修饰某个成员变量只能被外部访问,使用 attr_writer 修饰变量只能被修改,使用 attr_accessor 表示既可以被外部访问也可以被修改。修饰时使用的是 symbol。

class Person
  attr_reader :name
  attr_writer :age
  attr_accessor :sex
end

实际上以上代码会被翻译成以下形式

def name
  @name
end

def name=(value)
  @name = value
end

initialize #

initialze() 方法就是其它语言中的构造方法,用于构造对象时进行初始化操作。

def initialize(name)
  @name = name
  @age = 0
  @sex = 'male'
end

类变量 #

类变量使用 @@ 修饰,由类的实例共享,和成员变量不同,类变量必须先进行定义然后才能使用。 此外,类变量默认是 protected 的,只能在内部或子类中访问。

class Foobar
  @@counter = 0

  def initialize(name)
    @@counter += 1
  end

  def print_counter
    puts "counter is #{@@counter}"
  end
end

全局变量 #

全局变量使用 $ 修饰,使用前无需预先定义。通常不建议使用全局变量。

类对象 #

每个类都有一个类对象,同 Java 一样,使用 .class 来获得类对象。

puts 1.class

可以通过 is_a?() 来判断一个实例是不是某个类的对象

puts 1.is_a?(Integer)

类方法 #

类方法是属于类的方法,或者称作静态方法。调用时需要使用类本身而不是实例。 Ruby 中共有四种方式来定义类方法。

class Machine
  def hello
    puts 'hello member function'
  end
  # 四种方式
  def Machine.hello
    puts 'hello class function'
  end

  def self.hello2
    puts 'hello2 class function'
  end

  class << Machine
    def hello3
      puts 'hello3 class function'
    end
  end

  class << self
    def hello4
      puts 'hello4 class function'
    end
  end
end
m = Machine.new
m.hello
Machine.hello
Machine.hello2
Machine.hello3
Machine.hello4

单例方法 #

单例方法有两种定义方式

def m.singleMethod1
  puts 't1 single method'
end

class << m
  def singleMethod2
    puts 't2 single method'
  end
end

m.singleMethod1
m.singleMethod2

方法无法定义在对象中,所以单例方法不是定义在对象中,也不是定义在类中,因为这样就会被所有实例共享 实际单例方法是保存在 EigenClass 类中,又名特性类,每个对象都有这样一个类,可以通过 class 来获得。

eigenclass = class << m
  self
end
puts eigenclass.class
puts eigenclass.instance_methods.grep(/singleMethod./)

puts vs p #

puts 会自动调用对象的 to_s 方法,默认会打印对象的地址 p 会调用对象的 inspect 方法,默认会打印对象的成员变量

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

  def inspect
    'Result of inspect'
  end
end

item = Item.new('item01')
puts item # => #<Item:0x007fde4c177af0>
puts item.to_s # => #<Item:0x007fde4c177af0>
p item # => Result of inspect

class ItemList
  def initialize(name, items)
    @name = name
    @items = items
  end
end

items = ItemList.new('itemlist', [item])
puts items # => #<ItemList:0x007fde4c1778e8>
p items # => #<ItemList:0x007fde4c1778e8 @name="itemlist", @items=[Result of inspect]>
沪ICP备17055033号-2