1. 类

1.1 创建类

在Ruby中创建一个类的例子如下:

class Testdef initialize(name)@name = nameend
end

initialize是一个特殊的方法。当调用Test.new时,Ruby首先分配一些内存来保存未初始化的变量,然后调用对象的initialize方法,并把调用new时所使用的参数传入该方法。

实例变量是一个由"@"字符开头的名字。对象内的所有方法都可以访问实例变量,每个对象都有实例变量的一份拷贝。

Ruby有一个标准消息to_s,它可以发送给任何一个想要输出字符串表示的对象,例如:

test = Test.new('John')
test.to_s

在Ruby中,类永远都不是封闭的,总是可以向一个已有的类中添加方法,这同样适用于标准的内建类,例如:

class Testdef to_s"Name: #@name"end
end

1.2 继承和消息

继承允许创建一个类,作为另一个类的精炼和特化,例如:

class UITest < Testdef initialize(name, size)super(name)@size = sizeend
end

类定义行中的"<"说明UITest是Test的子类,当Ruby遇到方法调用时,它会查看方法所属的类,如果该类实现了和消息名称相同的方法,就运行这个方法,否则,就会查看其父类中的方法,以此追溯整个祖先链。如果最终没有找到合适的方法,Ruby通常会引发一个错误。

关键字super要求向当前对象的父类发送一个消息,要求它调用子类中的同名方法。Ruby默认以Object类作为其父类,即所有类的始祖都是Object,to_s即是Object类的实例方法之一。

1.3 对象和属性

对象的外部可见部分被称为其属性,例如:

class Testdef name@nameend
end
puts Test.name

Ruby提供了一种方便的快捷方式来创建对实例变量的访问方法,例如:

class Testattr_reader :name
end
puts Test.name

有些时候,需要能够在对象外部设置它的属性,可以创建一个名字以等号结尾的方法来达成目标,例如:

class Testdef name=(new_name)@name = new_nameend
end
Test.name = 'Marry'
puts Test.name

Ruby同样又提供了一种快捷方式来创建这类简单的属性设置方法,例如:

class Testattr_writer :name
end
Test.name = 'Marry'
puts Test.name

在设计一个类的时候,可以决定其具有什么样的内部状态以及这些内部状态对外界的表现形式。内部状态保存在实例变量中,通过方法暴露出来的外部状态,称之为属性,而类可以执行的其他动作,则是一般方法。

1.4 类变量和类方法

类变量被类的所有对象所共享,对一个给定的类来说,类变量只存在一份拷贝。类变量由两个"@"符开头,类变量在使用之前必须被初始化。通常,初始化就是在类定义中的简单赋值,例如:

class Test@@name = 'John'
end

类变量对类及其实例都是私有的,如果要在外部被访问,则需要编写方法,这个方法要么是一个实例方法,要么是类方法。

类方法和实例方法是通过它们的定义区别开来的,通过在方法名之前放置类名以及一个句点,来定义类方法,例如:

class Testdef Test.class_methodend
end

如果希望所有对象都共享同一个操作对象,可以使用单例模式,例如:

class Testprivate_class_method :new@@tester = nildef Test.create@@tester = new unless @@tester@@testerend
end
tester1 = Test.create
tester2 = Test.create

1.5 访问控制

Ruby提供了三种级别的保护:

1) Public: 方法可以被任何人调用,没有限制访问控制。方法默认是public的,除了initialize,它是private的。

2) Protected: 方法只能被定义了该方法的类或其子类的对象所调用。

3) Private: 方法不能被明确的接收者调用,其接收者只能是self。这意味着私有方法只能在当前对象的上下文中被调用。

可以使用public、protected和private三个函数为类或模块定义内的方法指定访问级别。如果使用时没有参数,这三个函数设置后续定义方法的默认访问控制,例如:

class Testprotecteddef method1endprivatedef method2endpublicdef method3end
end

另外,可以通过将方法名作为参数列表传入访问控制函数来设置它们的访问级别,例如:

class Test def method1enddef method2enddef method3enddef method4endpublic :method1 :method4protected :method2private :method3
end

1.6 变量

在Ruby中,变量是对象的一个引用,例如:

person1 = 'Tim'
person2 = person1
person1[0] = 'J'
puts person2 #Jim

在上例中,改变了person1的值,但是person1和person2都从"Tim"改为了"Jim"。这归结于变量保存的是对象引用而非对象本身。 可以通过使用String的dup方法来避免创建别名,例如:

person1 = 'Tim'
person2 = person1.dup
person1[0] = 'J'
puts person2 #Tim

可以通过冻结一个对象来阻止其他人对其进行改动,试图更改一个被冻结的对象,Ruby将引发一个TypeError异常,例如:

person1 = 'Tim'
person2 = person1
person1.freeze
person2[0] = 'J' #error

2. 容器  

2.1 数组

数组类含有一组对象引用,每个对象引用占据数组的一个位置。可以通过使用字面量,或显式创建Array对象,来创建数组,例如:

myarray1 = [1, 'one']
myarray2 = Array.new
myarray2[0] = 1
myarray2[1] = 'one'

数组由"[]"操作符来进行索引,下标从0开始。使用非负整数访问数组,将会返回处于该整数位置上的对象,如果此位置上没有对象,则返回nil。如果使用负整数访问数组,则从数组末端开始计数。

也可以使用一对数字"[start, count]"来访问数组,这将返回一个包含从start开始的count个对象引用的新数组,例如:

a = [1, 2, 3, 4, 5]
newarray = a[1, 3]

最后,还可以使用range来对数组进行索引,其开始和结束位置被两个或3个点分割开,两个点的形式包含结束位置,而3个点的形式不包含,例如:

a = [1, 2, 3, 4, 5]
newarray1 = a[1..3]
newarray2 = a[1...3]

"[]"操作符有一个相应的"[]="操作符,它可以设置数组中的元素,替换造成的任何间隙将由nil来填充。如果"[]="的下标是两个数字或者是range,那么原数组中的那些元素将被赋值语句右边的东西所替换。如果长度是0,那么赋值语句右边的东西将被插入到数组的起点位置之前。如果右边本身是一个数组,那么其元素将替换掉原数组对应位置上的东西。如果索引下标选择的元素个数和赋值语句右边的元素个数不一致,那么数组会自动调整其大小。

2.2 散列表

散列表和数组的相似处在它们都是被索引的对象引用的集俣,不过数组只能用整数来索引,而散列表可以用任何类型的对象来进行索引,随后可以通过键去索引散列表以获得其对应的值,例如:

myhash = {'one' => 1, 'two' => 2}

和数组相比,散列表有一个突出的优点:可以用任何对象做索引,然后它也有一个突出的缺点:它的元素是无序的,因此很难用hash来实现栈和队列。

2.3 迭代器

Ruby的迭代器是可以调用block的方法,Ruby的代码区块和C、Java等不同,它不是传统意义上的、将语句组织在一起的一种方式。首先,block在代码中只和方法调用一起出现,其次,在遇到block的时候并不立刻执行其中的代码。Ruby会记住block出现时的上下文然后执行方法调用。

在方法内部,block可以像方法一样被yield语句调用,每执行一次yield,就会调用block中的代码,例如:

def testyieldyieldyield
end
test {puts 'Hello World!'}

yield语句可以带有参数,参数值将传送给相关联的block,在block定义中,参数列表位于两个竖线之间,block可以有任意数量的参数。如果传递给block的参数是已存在的局部变蛳,那它们的值可能会因block的执行而改变。block也可以返回值给方法。

一些迭代器是Ruby的许多收集类型所共有的,比如find方法,例如:

myarray.find {|item| item == 1}

each可能是最简单的迭代器,它所做的就是连续访问收集的所有元素,例如:

myarray.each {|item| puts item}

collect迭代器从收集中获得各个元素并传递给block,block返回的结果被用来生成一个新的数组,例如:

[1, 2, 3].collect {|item| item+1}

inject迭代器可以遍历收集的所有成员以累计出一个值,例如:

[1, 3, 5].inject(0) {|sum, element| sum+element}

[Ruby] 类和容器相关推荐

  1. 【Ruby】Ruby 类案例

    阅读目录 Ruby类案例 保存并执行代码 Ruby类案例 下面将创建一个名为 Customer 的 Ruby 类,声明两个方法: display_details:该方法用于显示客户的详细信息. tot ...

  2. 通过@Import注解把类注入容器的四种方式

    文章目录 1. @Import导入的四种方式 2. 准备工作 ①:导入普通类ConfigA ②:导入`@Configuration`配置类ConfigB ③:导入`ImportSelector`的实现 ...

  3. 从一个例子开始体验轻量级类隔离容器 SOFAArk | SOFAChannel#11 直播整理

    <SOFA:Channnel/>,有趣实用的分布式架构频道. 本文根据 SOFAChannel#11 直播分享整理,主题:从一个例子开始体验轻量级类隔离容器 SOFAArk.回顾视频以及 ...

  4. Java的异常类和常用类、容器

    Java的异常类和常用类.容器 一.Java的异常类 1.异常的概念 2.异常的分类 3.try-catch语句 4.自定义异常类 二.Java的常用类 1.String类 2.StringBuffe ...

  5. AbstractAutowireCapableBeanFactory 类对容器生成的Bean 添加后置处理器

    BeanPostProcessor 后置处理器的调用发生在Spring IOC 容器完成对Bean 实例对象的创建和属性的依赖注入完成之后,在对Spring 依赖注入的源码分析过程中我们知道,当应用程 ...

  6. 模仿Spring实现一个类管理容器

    简介: 项目的初衷是独立作出一个成熟的有特色的IOC容器,但由于过程参考Spring太多,而且也无法作出太多改进,于是目的变为以此项目作为理解Spring的一个跳板,与网上的一些模仿Spring的框架 ...

  7. 第二周预习:异常类,常用类,容器

    异常类 异常 异常:在程序的运行过程中,发生了不正常的现象,阻止了程序的运行,我们称之为发生异常. Java使用throw关键字抛出一个Exception子类的实例表示异常发生. try-catch语 ...

  8. C++之模板类_容器_迭代器_算法_GCC_make

    站在编译器和C的角度剖析c++原理, 用代码说话 类模板基础 首先什么是模板: 模板就是把要处理的函数或类的类型参数化,表现为参数的多态性. 模板用来表现逻辑结构相同,但具体数据元素类型不同的对象的通 ...

  9. eclipse建工程时,出现“在项目中具有不受限制的类路径容器:JRE系统库”错误

    在相应的项目上点击右键出现构建路径选项中,将对应的库除去,然后再从新添相应的库即可. 亲测,就是这么简单..

  10. 在ECLIPSE导入项目后提示::具有不受限制的类路径容器:“JRE 系统库 [JVM 1.6.0]”

    工程右键->属性->Java构建路径->库->双击->执行环境->选择合适的.    如何选择合适的?查看自己的jdk版本--->打开cmd  输入java ...

最新文章

  1. oracle 取系统当前年份_oracle查询以当前年份为准的近些年数据
  2. 铲屎官福音:汪星人和喵星人的小情绪,AI 可以识别了
  3. Git reset , revert, checkout的区别和联系
  4. SAP支持服务的QA
  5. 质因数的个数 (分解质因数)
  6. Creator-配置MSVC调试器
  7. 深入vuex原理(上)
  8. pythonlambda回调函数_Python中如何借助lambda来给回调函数传参
  9. 二位四进制计数器_金三银四还在看JVM这一块?看完这篇万字JVM面试解析就够了...
  10. Android高级-Android操作SQL数据管理,增删改查
  11. flash位图技术研究篇(3):移动缓冲区域
  12. SimpleFs文件系统初步二(测试用的块设备构建)
  13. 高质量解读《高性能mysql》——第1章 MySQL架构与历史
  14. 重置计算机的本地策略,手把手教你win10系统本地组策略重置恢复默认的详细方案...
  15. 运输小猫(斜率优化)
  16. WiFi过敏?没准是心病
  17. L​I​N​U​X​环​境​中​部​署​J​A​V​A​项​目​步​骤
  18. Android 布局旋转 横屏竖屏
  19. 使用nslookup命令检查DNS服务
  20. Django项目中浏览器显示127.0.0.1拒绝我们的连接请求

热门文章

  1. PHPExcel 根据总列数生成EXCEL列名
  2. linux mysql show_Linux下 MySQL Show命令的使用
  3. 制作LINUX安装DEB,脚本中的函数报错怎么办?
  4. 安装软件后,在postinst中执行ldconfig无效?
  5. RSA加密:javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes
  6. NPAPI插件无法加载,有可能跟JDK相关
  7. 1970年代宇航员在月球上生活,如何实现电力供应
  8. 重复可记,证明没有忘记这回事
  9. VMWARE下UBUNTU扩展磁盘空间的办法
  10. 管理感悟:先做事,后做人