Footprint

We walk and learn


Project maintained by cellzero Hosted on GitHub Pages — Theme by mattgraham

读书笔记:Ruby基础教程第5版

Ruby version: 2.3.0

CH-08 类和模块


类的基本概念

类和实例

使用 new 方法创建实例。

继承

类的继承关系。

BasicObject
    | - Object
          | - Array
          | - String
          | - Hash
          | - Regexp
          | - IO
              | - File
          | - Dir
          | - Numeric
                | - Integer
                      | - Fixnum
                      | - Bignum
                | - Float
                | - Complex
                | - Rational
          | - Exception
          | - Time

根据对象查找所属的类时使用 instance_of? 方法。

根据类的继承关系反向追查对象是否属于某个类时使用 is_a? 方法。


创建类

class语句

使用 class 定义类,类名首字母必须大写。

initialize方法

使用 new 方法生成对象时,initialize 方法被调用。

存取器

定义 意义
attr_reader 只读
attr_writer 只写
attr_accessor 读写

特殊变量self

实例方法中,可以用 self 来引用方法的接收者。

调用方法时,如果省略了接收者,Ruby 就会默认把 self 作为该方法的接收者。

类方法

方法的接收者就是类本身的方法称为类方法。

类方法可以通过以下4中方式定义:

class << Hello
  def hello(name)
    puts "#{name} said hello"
  end
end
class Hello
  class << self
    def hello(name)
      puts "#{name} said hello"
    end
  end
end
def Hello.hello(name)
  puts "#{name} said hello"
end
class Hello
  def self.hello(name)
    puts "#{name} said hello"
  end
end

常量

类中可以定义常量,在类的外部可以使用 :: 来实现外部访问。

类变量

@@ 开头的变量称为类变量。从类外部访问类变量需要使用存取器,但 attr_accessor 等存取器不能使用,只能直接定义类变量的存取器。

限制方法调用

方法的访问级别有 publicprivateprotected 三种。

class AccTest
  def foo
    print "foo"
  end
  
  private :foo # 将foo方法设定为private
  
  public       # 不指定参数时,以下方法都被定义为public
  
  def bar
    print "bar"
  end

没有指定访问级别的方法默认为public,但initialize方法是个例外,它通常会被定义为private。


扩展类

在原有类上添加方法

继承

class Child < Father
  def foo
  end
end

别名与取消定义

alias

alias f_new f_ori    # 直接使用方法名
alias :f_new :f_ori  # 使用符号名

undef

undef f_name    # 直接使用方法名
undef :f_name   # 使用符号名

单例类

利用单例类定义,可以给对象添加方法(单例方法)。

方法的调用

简单的方法调用

obj.func(p1, p2, ..., pn)

在面向对象的世界,调用方法可以理解为“向对象发送消息”。上面的代码中接收者为 obj ,消息为 func ,括号中的为消息的参数。在调用方法时 () 可以省略。

带块的方法调用

obj.func(p1, p2, ..., pn) do |v1, v2, ... |
  block
end
obj.func(p1, p2, ..., pn) { |v1, v2, ... |
  block
}

可以使用 do ~ end{} 将块传递给方法。使用 do ~ end 时,可以省略参数列表的 ()。使用 {} 时,只有参数列表为空才可省略 ()

运算符形式的方法调用

四则运算等二元运算符,负号等一元运算符,指定数组、散列的元素下标的 [] 等,实际上都是方法。


方法的分类


方法的定义

def func_name(p1, p2, ..., pn)
  func_content
end

默认参数

def f(a, b=1, c)
  return a + b + c
end

f(10, 100)     # => 111
f(10, 2, 100)  # => 112

方法的返回值

def f(n)
  if n < 0 then
    return
  elsif n == 0 then
    return 0
  n
end

f(-1)   # => nil
f(0)    # => 0
f(1)    # => 1

定义带块的方法

参数个数不确定的方法

def f(a, *b)
  [a, b]
end

f(1)        # => [1, []]
f(1, 2, 3)  # => [1, [2, 3]]

关键字参数

def f(a: 1, b: 2)
  a * b
end
def f(a: 0, **b)
  [a, b]
end

f(a: 1)         # => [1, {}]
f(a: 1, x: 10)  # => [1, {:x=>10}]
def f(a:1, b:2)
  a * b
end

f({a: 10})
f(a: 10)
f(x: 10)    # => ArgumentError

额外内容

把数组分解为参数

def foo(a, b, c)
  a * b * c
end

foo(1, *[2, 3])

缩进

Ruby社区使用两个空白表示一个缩进。


Back