类 #
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]>