• Ruby使用类组织对象


    使用Object.new创建新对象,但是一次只使用一种方法,这是感受以对象为中心的Ruby编程的最佳方式之一。不过这种方式并不能很好地扩展,假如有一个正在运行地在线售票网站,然后其数据库必须处理数以百计地售票记录,那么可以在Ruby程序中寻找另外地一种方式去创建和操作类似的ticket的对象。
    Ruby有一套完整的编程技术用于批量地创建对象,从而不必对每一个ticket定义一个独立的price方法。与之前不同的是通过定义一个ticket类可以让每一个独立的ticket对象自动拥有一个price方法。这一点和其他高级语言的类很像。

    一、类的设计

    定义一个类:

    class Ticket
        def event
            "Can't really be specified yet..." 
        end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5

    一个特殊对象管理的信息和数据体现了对象的状态。需要完成以下事情:
    1、设置或重置对象的状态
    2、回读状态
    在Ruby对象中,提供了便捷的数据存储和取回的机制:实例变量
    实例变量使得独立的对象可以记住状态。实例变量和其他变量的机制十分相像:赋值,然后回读它们的值,可以把它们相加、打印。
    3、实例变量总是以一个@开头
    4、实例变量仅仅在它归属的对象内部可见
    5、一个实例变量在类的其中一个方法中初始化。然后可以在这个类的任何方法中使用

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

    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}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行这段代码,将得到

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    二、使用语法糖的setter方法

    语法糖(Syntax sugar)是计算机科学中的术语,指的是在编程语言中,使用更易理解和更具有描述性的语法来代替较为复杂或低级的语法。
    语法糖可以使代码更易读、易写,也可以帮助程序员更快速地理解和领会代码的含义。它通常不会改变程序的行为,但可以使代码更易于维护和修改。
    例如,在许多编程语言中,可以使用for-each循环来遍历数组和集合,而不需要像使用低级语言那样手动控制索引。这是一种语法糖,它使程序更易于编写和理解。
    另一个例子是在许多语言中,可以使用lambda表达式(或称为匿名函数)来定义函数,而不需要使用声明完整的函数名称和定义函数体。这种语法糖可以使代码更简洁、更灵活。
    能够编写以等号结尾的方法,实际上是Ruby提供了调用这种类型方法的语法糖来创造一些有趣的可能性。
    在Ruby中,setter方法是一种用于修改变量的方法,通过在变量名后面添加一个冒号(:)和一个参数来实现。这种语法糖可以让代码更加简洁和易读。

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在上面的示例中定义了一个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)来读取这些属性的值。

    class Person  
      attr_reader :name, :age  
    end  
      
    person = Person.new  
    person.name = "John" # 报错,name属性不可写  
    puts person.name    # 输出 "John"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

    四、继承和Ruby类层级结构

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

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

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

    class Animal < LivingThing  
      # code specific to Animals  
    end
    
    • 1
    • 2
    • 3

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

    在Ruby中,有几种类型的继承:
    1、单继承:一个类只能继承自一个父类。如上述示例所示。
    2、混入(Mixin):这是一种将模块(module)的功能添加到类中的方式。模块是可以包含方法和常量的命名代码块。

    module AnimalFeatures  
      def has_heartbeat  
        true  
      end  
    end  
      
    class Animal < LivingThing  
      include AnimalFeatures  
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里,Animal类不仅继承了LivingThing,还混入了AnimalFeatures模块。
    3. 多重继承:在Ruby中,一个类可以继承自多个父类。这是通过使用<符号在类定义中一次引用多个父类来实现的。然而,多重继承可能会导致一些复杂的问题,特别是当不同的父类有同名的方法或属性时。

    class Animal < Creature  
      # Animal's code  
    end  
      
    class Vehicle < Creature  
      # Vehicle's code  
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    五、常量

    在Ruby中,常量(Constant)是程序中不会改变的值。Ruby中的常量具有全局作用域,可以在程序的任何地方访问和修改。
    在Ruby中,常量定义使用全大写字母,并且单词之间使用下划线(_)连接。例如,下面是一个常量的定义:

    class MyClass  
      # 定义一个常量  
      MY_CONSTANT = "Hello, World!"  
      
      def initialize  
        # 在方法中使用常量  
        puts MY_CONSTANT  
      end  
    end  
      
    obj = MyClass.new # 输出 "Hello, World!"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    带有@Transactional注解的方法事务失效问题以及解决方法
    break和continue在循环和嵌套循环中的作用 简单试验
    docker安装minio及minio的使用
    Python邮件发送程序代码
    mapboxgl 中插值表达式的应用场景
    windows部署java环境
    Stable Diffusion中的embedding
    GD32搭建Keil MDK开发环境
    工业智能网关BL110应用之三十五: 如何连接配置金鸽MQTT云服务器
    删除链表的倒数第n个节点的最优算法实现
  • 原文地址:https://blog.csdn.net/weixin_44014982/article/details/133898475