Ruby 开发(四) - 面向对象(中)

197 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

三、类的方法

对于类来说,方法就是类中执行类的行为的成员,类的所有行为都已方法的形式呈现。在类中定义的方法称之为方法,在类外面定义的方法称之为函数。

Ruby 中定义方法使用 def 关键字并且要以 end 关键字结尾,语法格式如下:

def 方法名(参数1, 参数2, ...)
# 方法体
end

方法中的包裹参数的括号可以省略,方法名和参数之间需要通过空格隔开,方法的参数为空时,调用方法可以省略括号。

class Animal
  def walking(road)
    puts "它正在" + road + "上行走"
  end

  def eating name, food
    puts name + "正在吃" + food
  end

  def running
    puts "奔跑中...."
  end
end

animal = Animal.new
animal.walking("康庄大道")
animal.eating("皮皮", "冻干")
animal.running

执行上述代码,输出结果如下:

它正在康庄大道上行走
皮皮正在吃冻干
奔跑中....

参数的默认值

方法中可以为一些参数设置一个默认值。

修改上述 Animal 类中的 eating 方法,增加默认值,并通过实例化对象调用该方法。

def eating name, food="小鱼干"
  puts name + "正在吃" + food
end

animal.eating("皮皮")
animal.eating("皮皮", "冻干")

执行上述代码,输出内容如下:

皮皮正在吃小鱼干
皮皮正在吃冻干

方法的返回值

Ruby 中使用 return 关键字显示的定义方法的返回值。

class Animal
  def getName()
    return "皮皮"
  end
end

animal = Animal.new
name = animal.getName
puts name

执行上述代码,输入内容如下:

皮皮

特殊方法

Ruby 中除了可以对类扩展,也可以对类中方法进行扩展,称之为特殊方法。

# 定义一个对象
class Cat

end

cat = Cat.new

def cat.jump
  puts "喵咪喜欢跳来跳去"
end

cat.jump


cat2 = Cat.new
cat2.jump

执行上述代码,输出结果如下:

喵咪喜欢跳来跳去
Traceback (most recent call last):
/ruby-oop/ex9.rb:18:in `<main>': undefined method `jump' for #<Cat:0x00007faa2d836768> (NoMethodError)

定义的特殊方法需要与实例对象绑定,并且只对绑定的实例对象有效,其他实例化对象无法调用。

类方法

可以直接通过类名调用的方法称之为类方法,类方法的定义需要实用类名和点运算符作为方法名的前缀。

class Hero
  def self.say
    puts "这是在类内部定义的可以通过类名直接调用的方法"
  end

  def Hero.hello
    puts "这也是在类内部定义的可以通过类名直接调用的方法"
  end
end

def Hero.hi
  puts "这是在类外定义的可以直接通过类名调用的类方法"
end

Hero.hi
Hero.say
Hero.hello

输入上述代码,执行结果如下:

这是在类外定义的可以直接通过类名调用的类方法
这是在类内部定义的可以通过类名直接调用的方法
这也是在类内部定义的可以通过类名直接调用的方法

四、实例变量和类变量

Ruby 中为了各个模块之间共享数据,提供了两种存放共享数据的变量,既实例变量和类变量。Ruby 中可以声明实例变量的位置有以下几个:

  • 顶层/顶层方法
  • 类/类方法
  • 模块/模块方法

顶层/顶层方法中定义的实例变量

在程序文件顶层定义的实例变量对整个应用程序中的顶层表达式函数都有效,在类和模块中定义的实例变量可以被当前类或者模块中的表达式方法,在类方法中生命的实例变量可以被当前类下的所有方法中调用。

实例变量的命名需要以一个 @ 符号开头。

@name = "Tom"

class Cat
  @color = "黄色"
  def init
    @weight = "3kg"
  end
  def show
    puts "名字是:#@name, 体重为:#@weight, 颜色为:#@color,"
  end
end

cat = Cat.new
cat.init
cat.show

执行上述代码,输出结果为:

名字是:, 体重为:3kg, 颜色为:,

根据上述的输出结果可以确定,顶层定义的 name 变量和类中定义的 color 变量都无法在 show 方法中方,只有在 init 方法中定义的变量 weight 可以在 show 方法中被访问到。

类变量

类变量可以在各个类之间共享数据,Ruby 中允许定义类变量的位置和实例变量的位置相同,实例变量的变量名需要 @@ 开头。

@@master = "Strange"

class Wizard
  def say
    puts "#@@master 才是至尊法师"
  end
end

wizard = Wizard.new
wizard.say

执行上述代码,输出结果如下:

Strange 才是至尊法师
ex13.rb:1: warning: class variable access from toplevel

运行结果中给出了警告信息。

由于类变量的作用域在整个程序范围内,所以通常会保存一些程序级的配置性信息。