Ruby使用类组织对象

使用Object.new创建新对象,但是一次只使用一种方法,这是感受以对象为中心的Ruby编程的最佳方式之一。不过这种方式并不能很好地扩展,假如有一个正在运行地在线售票网站,然后其数据库必须处理数以百计地售票记录,那么可以在Ruby程序中寻找另外地一种方式去创建和操作类似的ticket的对象。

Ruby有一套完整的编程技术用于批量地创建对象,从而不必对每一个ticket定义一个独立的price方法。与之前不同的是通过定义一个ticket类可以让每一个独立的ticket对象自动拥有一个price方法。这一点和其他高级语言的类很像。

一、类的设计

定义一个类:

ruby 复制代码
class Ticket
    def event
        "Can't really be specified yet..." 
    end
end

一个特殊对象管理的信息和数据体现了对象的状态。需要完成以下事情:

1、设置或重置对象的状态

2、回读状态

在Ruby对象中,提供了便捷的数据存储和取回的机制:实例变量

实例变量使得独立的对象可以记住状态。实例变量和其他变量的机制十分相像:赋值,然后回读它们的值,可以把它们相加、打印。

3、实例变量总是以一个@开头

4、实例变量仅仅在它归属的对象内部可见

5、一个实例变量在类的其中一个方法中初始化。然后可以在这个类的任何方法中使用

ruby 复制代码
class Person
    def set_name(string)
        puts "Setting person's name..."
        @name = string
    end
    def get_name
        puts "Returning the person's name..."
        @name
    end
end

joe = Person.new
joe.set_name("Joe")
puts joe.get_name

类的初始化

编写一个类时,可以定义一个特殊的方法initialize。

这样这个方法将在每次创建类的实例时被创建,在创建对象时可以使用这个自动初始化的过程来设置对象的状态。这里在每个ticket对象被创建时,给它们指定一个地点和时间,可以把正确的值作为传递参数发送给Ticket.new,同样地,这些参数将被自动地发送给initialize。

ruby 复制代码
class Ticket
    def initialize(venue, date)
        @venue = venue
        @date = date
    end
    def venue
        @venue
    end
    def date
        @date
    end
end
th = Ticket.new("Town Hall", "11/12/13")
cc = Ticket.new("Convention Center", "12/13/14")
puts "We've created two tickets."
puts "The first is for a #{th.venue} event on #{th.date}"
puts "The second is for an event on #{cc.venue} event on #{cc.venue}"

运行这段代码,将得到

bash 复制代码
We've created two tickets.
The first is for a Town Hall event on 11/12/13
The second is for an event on Convention Center event on Convention Center
Setting person's name...
Returning the person's name...
Joe

二、使用语法糖的setter方法

语法糖(Syntax sugar)是计算机科学中的术语,指的是在编程语言中,使用更易理解和更具有描述性的语法来代替较为复杂或低级的语法。

语法糖可以使代码更易读、易写,也可以帮助程序员更快速地理解和领会代码的含义。它通常不会改变程序的行为,但可以使代码更易于维护和修改。

例如,在许多编程语言中,可以使用for-each循环来遍历数组和集合,而不需要像使用低级语言那样手动控制索引。这是一种语法糖,它使程序更易于编写和理解。

另一个例子是在许多语言中,可以使用lambda表达式(或称为匿名函数)来定义函数,而不需要使用声明完整的函数名称和定义函数体。这种语法糖可以使代码更简洁、更灵活。

能够编写以等号结尾的方法,实际上是Ruby提供了调用这种类型方法的语法糖来创造一些有趣的可能性。

在Ruby中,setter方法是一种用于修改变量的方法,通过在变量名后面添加一个冒号(:)和一个参数来实现。这种语法糖可以让代码更加简洁和易读。

ruby 复制代码
class Person  
  attr_accessor :name, :age  
  
  def initialize(name, age)  
    @name = name  
    @age = age  
  end  
  
  def name=(name)  
    @name = name.capitalize  
  end  
  
  def age=(age)  
    @age = age.to_i  
  end  
end  
  
person = Person.new("john smith", "25")  
puts person.name    # 输出 "John Smith"  
puts person.age      # 输出 25  
  
person.name = "jane doe"  
puts person.name    # 输出 "Jane Doe"  
  
person.age = "30"  
puts person.age      # 输出 30

在上面的示例中定义了一个Person类,它有两个属性name和age,以及它们的setter方法。在name的setter方法中,我们将传入的名称字符串转换为首字母大写的形式。在age的setter方法中,我们将传入的字符串转换为整数。通过使用attr_accessor方法,我们可以使用简洁的语法糖来访问和修改变量,而不需要显式地定义getter和setter方法。

三、属性和attr_*方法体系

在Ruby中,属性(attributes)是对象的实例变量(instance variables),它们是对象的内部状态,用于存储对象的数据。属性在类中定义,并且可以通过类的实例进行访问。

在Ruby中,有多种方式来定义属性,其中最常见的是使用attr_reader和attr_accessor方法体系。

1、attr_reader方法:这个方法用于定义只读属性,它防止通过实例对属性进行写操作,只允许通过实例进行读操作。它接受一个或多个属性名称作为参数,然后返回一个类型检查的访问器方法(getter method)来读取这些属性的值。

ruby 复制代码
class Person  
  attr_reader :name, :age  
end  
  
person = Person.new  
person.name = "John" # 报错,name属性不可写  
puts person.name    # 输出 "John"

2、attr_accessor方法:这个方法用于定义可读可写属性,它允许通过实例对属性进行读写操作。它接受一个或多个属性名称作为参数,然后返回一个类型检查的访问器方法(getter和setter方法)来读取和修改变量的值。

ruby 复制代码
class Person  
  attr_accessor :name, :age  
  
  def name=(name)  
    @name = name.capitalize  
  end  
end  
  
person = Person.new  
person.name = "John" # 输出 "John"  
puts person.name    # 输出 "John"  
person.age = "25"     # 输出 25  
puts person.age      # 输出 25

使用attr_accessor方法定义的属性,如果没有显式定义访问器方法(getter和setter方法),则默认只允许通过实例进行读操作。如果需要显式定义访问器方法,则需要在定义属性后使用标准的getter和setter方法体系来定义它们。

四、继承和Ruby类层级结构

继承和Ruby的类层级结构紧密相关。在Ruby中,类是一种第一级的对象,这意味着你可以像其他对象一样创建和操作类。Ruby的类具有很多属性和方法,其中之一就是继承。

继承是面向对象编程中的一个重要概念,它允许我们在已有的类(父类或超类)的基础上创建新的类(子类)。子类继承并能使用父类的所有属性和方法,同时还可以定义自己特有的属性和方法。

在Ruby中,使用<符号来定义一个类继承另一个类。例如:

ruby 复制代码
class Animal < LivingThing  
  # code specific to Animals  
end

这里,Animal类继承了LivingThing类。这意味着Animal类可以访问LivingThing类的所有属性和方法,同时还可以定义自己特有的属性和方法。

在Ruby中,有几种类型的继承:

1、单继承:一个类只能继承自一个父类。如上述示例所示。

2、混入(Mixin):这是一种将模块(module)的功能添加到类中的方式。模块是可以包含方法和常量的命名代码块。

ruby 复制代码
module AnimalFeatures  
  def has_heartbeat  
    true  
  end  
end  
  
class Animal < LivingThing  
  include AnimalFeatures  
end

这里,Animal类不仅继承了LivingThing,还混入了AnimalFeatures模块。

  1. 多重继承:在Ruby中,一个类可以继承自多个父类。这是通过使用<符号在类定义中一次引用多个父类来实现的。然而,多重继承可能会导致一些复杂的问题,特别是当不同的父类有同名的方法或属性时。
ruby 复制代码
class Animal < Creature  
  # Animal's code  
end  
  
class Vehicle < Creature  
  # Vehicle's code  
end

五、常量

在Ruby中,常量(Constant)是程序中不会改变的值。Ruby中的常量具有全局作用域,可以在程序的任何地方访问和修改。

在Ruby中,常量定义使用全大写字母,并且单词之间使用下划线(_)连接。例如,下面是一个常量的定义:

ruby 复制代码
class MyClass  
  # 定义一个常量  
  MY_CONSTANT = "Hello, World!"  
  
  def initialize  
    # 在方法中使用常量  
    puts MY_CONSTANT  
  end  
end  
  
obj = MyClass.new # 输出 "Hello, World!"
相关推荐
憧憬成为原神糕手几秒前
c++_list
开发语言·c++
idealzouhu3 分钟前
Java 并发编程 —— AQS 抽象队列同步器
java·开发语言
爱吃油淋鸡的莫何3 分钟前
Conda新建python虚拟环境问题
开发语言·python·conda
闲人编程11 分钟前
Python实现日志采集功能
开发语言·python·fluentd·filebeat·日志采集
Sol-itude17 分钟前
关于MATLAB计算3维图的向量夹角总是不正确的问题记录
开发语言·matlab·问题解决·向量
奔驰的小野码30 分钟前
java通过org.eclipse.milo实现OPCUA客户端进行连接和订阅
java·开发语言
小川_wenxun43 分钟前
优先级队列(堆)
java·开发语言·算法
惜缘若水1 小时前
【SpinalHDL】Scala编程之伴生对象
开发语言·scala·spinalhdl
惜缘若水1 小时前
【SpinalHDL】Scala/SpinalHDL联合编程之实例化
开发语言·scala·spinalhdl
徐霞客3201 小时前
对于C++继承中子类与父类对象同时定义其析构顺序的探究
开发语言·c++