`
fireDragonpzy
  • 浏览: 466621 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

ruby base之类和对象

阅读更多
1、定义
若某个类被定义过,此时又用相同的类名进行定义,意味着对原有的类进行追加(重定义同一个类时,意味着对原有定义进行补充,不会覆盖原来的定义。而重定义方法时,则会覆盖原有定义。

2、变量
在ruby中,只有方法可以操作实例变量,因此可以说Ruby中的封装是强制性的。在对象外部不可以直接访问,只能通过接口方法访问。
class Person
  def name
    @name
  end
  def gender
    @gender
  end
  def age
    @age
  end
end

people = Person.new('Tom', 'male', 15)
puts people.name
puts people.gender
puts people.age

在Ruby中,一个对象的内部属性都是私有的。上面的代码中,我们定义了方法name,gender,age三个方法用来访问Person类实例对象的实例变量。注意name,gender,age访问只能读取相应实例变量,而不能改变它们的值。
我们也可以用成员变量只读控制符attr_reader来达到同样的效果。
class Person
  attr_reader :name, :gender, :age
end

类似地,我们可以定义方法去改变成员变量的值。
class Person
  def name=(name)
    @name=name
  end
  def gender=(gender)
    @gender=gender
  end
  def age=(age)
    @age=age
  end
end

people = Person.new('Tom', 'male', 15)
people.name = "Henry"
people.gender = "male"
people.age = 25

也可以用成员变量写控制符attr_writer来达到同样的效果。
class Person
  attr_writer :name, :gender, :age
end

我们也可以使用attr_accessor来说明成员变量既可以读,也可以写。
class Person
  attr_accessor :name, :gender, :age
end

也可以使用attr控制符来控制变量是否可读写。attr 只能带一个符号参数, 第二个参数是一个 bool参数,用于指示是否为符号参数产生写方法。它的默认值是 false,只产生读方法,不产生写方法。
class Person
  attr :name, true #读写
  attr :gender, true #读写
  attr :age, true #读写
  attr :id, false #只读
end

注意attr_reader,attr_writer,attr_accessor和attr不是语言的关键字,而是Module模块的方法。
class Test
  attr_accessor :value
end
puts Test.instance_methods - Test.superclass.public_methods
#执行结果为:
value
value=

上面代码中, 我们使用Test.instance_methods 得到Test 类所有的实例方法, 使用Test.superclass.public_methods得到Test父类所有的实例方法,然后相减就得到Test类不包含父类的所有的实例方法。
由于instance_methods方法返回值为一个Array,所以我们作差值运算
3、特殊方法与特殊类
特殊方法是指某实例所特有的方法。一个对象有哪些行为由对向所属的类决定,但是有时候,一些特殊的对象有和其他对象不一样的行为,在多数程序设计语言中,例如C++和Java,我们必须定义一个新类,但在Ruby中,我们可以定义只从属于某个特定对象的方法,这种方法我们成为特殊方法(Singleton Method)。
class SingletonTest
  def info
    puts "This is This is SingletonTest method"
  end
end
obj1 = SingletonTest.new
obj2 = SingletonTest.new
def obj2.info
  puts "This is obj2"
end
obj1.info
obj2.info
执行结果为:
This is This is SingletonTest method
This is obj2

有时候,我们需要给一个对象定义一系列的特殊方法,如果按照前面的方法,那么只能一个一个定义:
def obj2.singleton_method1
end
def obj2.singleton_method2
end

def obj2.singleton_method3
end
……
def obj2.singleton_methodn
end

这样做非常繁复麻烦,而且无法给出一个统一的概念模型,因此Ruby提供了另外一种方法,
class << obj
  ……
end

obj是一个具体的对象实例,class << 代表它的特殊类。
class SingletonTest
  def meth1
    puts "This is meth1"
  end
  def meth2
    puts "This is meth2"
  end
end

obj1 = SingletonTest.new
obj2 = SingletonTest.new

class << obj2
  def meth1
    puts "This is obj2's meth1"
  end
  def meth2
    puts "This is obj2's meth2"
  end
end
obj1.meth1
obj1.meth2
obj2.meth1
obj2.meth2
执行结果为:
This is meth1
This is meth2
This is obj2's meth1
This is obj2's meth2

4、类变量与类方法
1)类变量在使用前必须初始化,类变量在使用前必须初始化;类变量是私有的,在类外无法直接访问,你只能通过实例方法和类方法去访问它。
同样,类方法是属于一个类的方法,定义类方法时需要在方法前加上类名
2)Ruby和C++/Java的一个显著不同是存取控制是程序运行时决定的而不是静态绑定的。所以只有在访问一个受限制的方法时才会产生运行时错误。
3)方法的存取控制有三种:
  公有方法(Public Method)
      方法在任何地方都可以被调用,这是方法的默认存取控制。除了initialize和initialize_cpoy方法,他们永远是私有方法。
  保护方法(Protected Method)
      方法只能被定义这个方法的类自己的对象和这个类的子类的对象所访问。
  私有方法(private Method)
      方法只能被定义这个方法的类的对象自己访问,即使是这个类的其他对象也不能访问。
Ruby中的保护方法和私有方法与一般面向对象程序设计语言的概念有所区别,保护方法的意思是方法只能方法只能被定义这个方法的类自己的对象和子类的对象访问,私有方法只能被对象自己访问。
class Test
  def method1 #默认为公有方法
    …
  end
  protected #保护方法
  def method2
    …
  end
  private #私有方法
  def method3
  end
  public
  def test_protected(arg) #arg是Test类的对象
    arg.method2 #正确,可以访问同类其他对象的保护方法
  end
  def test_private(arg) #arg是Test类的对象
    arg.method3 #错误,不能访问同类其他对象的私有方法
  end
end

obj1 = Test.new
obj2 = Test.new
obj1.test_protected(obj2)
obj1.test_private(obj2)

也可以使用以下更简单的形式:
class Test
  def method1
    ...
  end
  def method2
    ...
  end
  def method3
    ...
  end
  def methdo4
    ...
  end
  public :method1
  protected :method2
  private :method3, :method4
end

Ruby和C++/Java的一个显著不同是存取控制是程序运行时决定的而不是静态绑定的。所以只有在访问一个受限制的方法时才会产生运行时错误。
5、元类
在Ruby中一切都是对象。类和实例对象都是对象。这句话听起来有点拗口,让我们来看一个例子:
class Person
  def initialize(name, gender, age)
    @name = name
    @gender = gender
    @age = age
  end
end
a = Person.new('Tom', 'male', 15)
puts a.object_id => 22429840
puts Person.object_id => 22429960

没错,类也是对象,这是Ruby和C++/Java的一个显著不同,在C++/Java中,类仅仅是一个数据抽象,并没有类也是对象这样的概念。而在Ruby中存在着元类的概念,类也是对象,所有类都是元类的实例对象。和C++/Java相比,Ruby的面向对象程度更高。
可以看到,类对象和实例对象一样有自己的ojbect_id,你可以象调用一个实例对象的方法一样去用它去调用类方法。所有类对象的类是Class类,Oject类是所有类的基类。
irb(main):003:0> Object.class
=> Class
irb(main):004:0> Object.superclass
=> BasicObject
irb(main):004:0> BasicObject.superclass
=> 

这样,我们可以从另一个角度去理解类变量与类方法,类变量就是一个类对象的实例变量,类方法就是指一个类对象类的特殊方法。
类方法具体可分为两种:第一种是在所有的类的父类Class中定义的,且被所有的类所共享的方法;第二种是各个类所特有的特殊方法。
类方法中的self指的是类本身,这点需要牢记,这样我们可以使用多种方式定义类方法。
class Test
  #定义类方法方式1
  def Test.meth1
    # ...
  end
  #定义类方法方式2
  def self.meth2
    # ...
  end

  #定义类方法方式3只能放在类定义里面
  class << Test
    def meth3
      # ...
    end
  end
  #定义类方法方式4
  class << self
    def meth4
      # ...
    end
  end
end

6、Ruby 的动态性
class UndefTest
  def meth
    puts "This is meth"
  end
end
obj1 = UndefTest.new
obj1.meth
class UndefTest
  undef_method(:meth)或者undef meth
end
obj1.meth
执行结果为:
This is meth
test.rb:14: undefined method `meth' for #<UndefTest:0x2ac8240> (NoMethodError)
分享到:
评论

相关推荐

    Ruby语言教程和经典案例

    这有助于理解如何使用类和对象来管理复杂的数据和行为。 - **元编程实例**:Ruby支持强大的元编程能力,如`method_missing`、`define_method`等特性。这些功能允许开发者在运行时动态生成或修改类和对象的行为,为...

    ruby-使用ruby实现的算法之加密解密算法.zip

    在Ruby中,可以使用`OpenSSL::Cipher`类的`new`方法创建一个AES对象,然后进行加密和解密操作。 4. **RSA加密** - RSA是一种非对称加密算法,拥有公钥和私钥。公钥用于加密,私钥用于解密。Ruby的`OpenSSL::PKey::...

    ruby_base

    Ruby是一种面向对象的、动态类型的编程语言,以其简洁、优雅的语法和强大的元编程能力而闻名。"ruby_base"这个标题可能是指一个基础的Ruby学习资源或者教程集合,旨在帮助初学者掌握Ruby语言的核心概念。 在Ruby中...

    Ruby的25个编程细节(技巧、实用代码段)

    在Ruby中,`try` 方法是一个非常有用的功能,它允许我们安全地访问对象的方法或属性,即使该对象为 `nil` 也不会抛出异常。相反,如果没有找到对象或者对象为 `nil`,`try` 会返回 `nil`。 **示例代码:** ```ruby ...

    crystal-ruby-marshal:使用Crystal进行元数据和非元数据的Ruby对象

    这对于读取诸如Rack会话对象之类的东西很有用,这些对象通常是base64编码的,加密的编组Ruby对象-否则在Crystal应用程序中将无法访问。怪癖该项目仍处于试验阶段。 目前正在积极开发Marshal#dump支持,目前尚不支持...

    模块的力量:Ruby中include与extend的深度解析

    - **面向对象**:Ruby几乎所有的元素都是对象,包括数字和符号,这使得面向对象编程变得非常直观和强大。 - **自动内存管理**:内置的垃圾回收机制自动处理内存分配和释放,大大减轻了程序员的工作负担。 - **灵活的...

    Ruby on Rails入门例子

    模型类继承自`ActiveRecord::Base`,可以直接与数据库表进行交互,如定义属性、验证规则和关联。 9. **测试**:Rails鼓励TDD(测试驱动开发),提供Rspec和MiniTest等测试框架。你可以在`test`目录下编写测试用例,...

    ruby on rails 2.1 what is new (CN)

    ### Ruby on Rails 2.1 新特性详解...以上就是Ruby on Rails 2.1版本的一些主要新特性和改进之处。这些更新不仅提升了开发效率,还增强了应用的功能性和稳定性,对于正在使用Rails进行开发的团队来说是非常值得升级的。

    Pro Active Record. Databases with Ruby and Rails

    - **集成方式**:在Rails中,Active Record是核心ORM(Object-Relational Mapping)组件,几乎所有的模型类都会继承自`ActiveRecord::Base`。 - **关联关系**:Active Record支持多种类型的关联关系,如一对一、一...

    Lua进阶教程(三)面向对象编程.pdf

    **类(Class)**:类是一个创建对象的可扩展模板,定义了一组属性(成员变量)和方法(行为)。类提供了对象的状态和行为的初始定义。 **对象(Object)**:对象是类的一个实例。当一个类被实例化时,就创建了一个对象...

    对优化Ruby on Rails性能的一些办法的探究

    随着Web应用程序变得越来越复杂,性能优化成为了确保用户满意度和提高系统效率的关键步骤之一。Ruby on Rails(简称Rails),作为一个流行的Web开发框架,虽然提供了丰富的功能和快速的开发体验,但也可能会面临性能...

    Laravel开发-base-fw

    它的设计灵感来源于 Ruby on Rails,并以其优雅的语法、强大的功能和丰富的社区支持,成为了 PHP 世界的首选框架之一。"base-fw-lrv-5.3-master" 这个文件名暗示我们讨论的是 Laravel 5.3 版本的基础框架。 **1. ...

    train_system:Ruby和Rails Ruby数据库基础知识火车系统,库(两天项目)

    Ruby是一种面向对象的、动态类型的编程语言,以其简洁、优雅的语法和强大的元编程能力著称。与Ruby搭配使用的Rails框架是Web开发领域的一个热门选择,它遵循“约定优于配置”(Convention Over Configuration)的...

    Agile Web Development with Rails

    - **DRY原则**(Don't Repeat Yourself):这一原则贯穿于整个Rails框架之中,旨在通过自动化工具和模板减少代码冗余。 - **约定优于配置**(Convention Over Configuration):Rails提供了一系列默认配置,开发人员...

    RailsTutorial_DemoApp:Ruby on Rails教程的演示应用程序

    在 Rails 中,模型通常继承自 ActiveRecord::Base 类,允许通过 Active Record ORM(对象关系映射)操作数据库记录。 2. **View**: 视图是用户看到和与之交互的部分,通常由 HTML、CSS 和 JavaScript 组成。Rails ...

    base_app:基本Laravel应用程序

    5. **视图**:视图是用户看到和与之交互的界面。Laravel支持Blade模板引擎,允许开发者创建动态和结构化的HTML页面。 6. **数据库迁移**:Laravel的数据库迁移系统允许开发者在多个环境中保持数据库结构的一致性。`...

    rails_simple_auth:Ruby on Rails简单身份验证应用程序

    在Ruby on Rails框架中,构建一个简单的身份验证应用程序是开发Web应用的基础步骤之一。这个名为"rails_simple_auth"的项目,旨在提供一个基础的身份验证解决方案,帮助开发者理解如何在Rails应用中实现用户登录、...

    Agile Web Development with Rails中文版 3rd Edition

    - **模型(Model)**:负责处理应用数据逻辑的部分,通常是通过继承自`ActiveRecord::Base`类来实现。 - **视图(View)**:展示数据的部分,通常由HTML、CSS和JavaScript组成。 - **控制器(Controller)**:处理...

    un-uploader-demo:Ember 应用程序的全栈上传工作流示例

    在文件上传方面,Ember 只是解决方案的一部分,我们认为提供一个端到端的实现来演示真实世界的上传和处理工作流程是一个好主意,而不仅仅是 Base64 编码表单数据和将它作为 JSON 对象中的字符串发送 - 不要这样做。...

    prototype1.4中文手册

    ##### 5.4 在 prototype.js 中定义新的对象和类 - **ThePrototype object**:Prototype 的根对象。 - **TheEnumerable object**:实现了 `each` 方法及其他集合操作的基础类。 - **TheHash object**:键值对集合。 -...

Global site tag (gtag.js) - Google Analytics