Ruby元编程-学习笔记(四)-类定义
来源:互联网 发布:oracle恢复原来的数据 编辑:程序博客网 时间:2024/05/21 07:59
类定义
在类或模块定义时,其自身充当了当前对象self的角色,类和模块也都是对象,与方法和块相同,类定义也会返回最后一条语句的值.
- 1
- 2
- 3
- 4
- 5
当前类
尽管self可以获得当前对象,但并不能获得当前类,每当通过class关键字打开一个类时,这个类就成为当前类.
- 1
- 2
- 3
- 4
- 5
- 6
class关键字必须指定类名才可以打开类,对于未知类名就可以修改当前类,可以使用class_eval().
class_eval()
Module#class_eval()方法会在一个已存在类的上下文中执行一个块.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
class_eval()方法与instance_eval()方法并不相同, instance_eval()方法仅会修改self(特定情况下也会修改当前类),而\calss_eval()方法会同时修改self和当前类.
对于二者的选择,若只想打开一个对象,并不在乎是不是类,使用instance_eval更好;而若是希望打开类,则使用class_eval()更好.
类实例变量
由于类是Class的实例,类名是常量,故而当self由当前类充当时所定义的变量即为类实例变量.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
类变量
类变量与实例变量不同, 它们可以被子类或类的实例所引用, 类似java静态成员.
- 1
- 2
- 3
- 4
- 5
- 6
这种情况不就破坏了class域作用门的性质, 得到这种结果是因为类变量并不真正属于类,它们属于类体系结构, 由于@@v定义与man顶级作用域中,它属于main的类Object,所以也属于Object所有的后代,而MyClass继承自Object,因此也共享了这个类变量.
单件方法
Ruby允许给单个对象增加一个方法, 该方法只对这个对象有效,称为单件方法.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
从上述代码可以看出同样是String类对象的str1和str2, str1有single_method方法,而str2没有, 还记得前面讲过,对象保存的只是一组实例变量和它自身类的引用,对象的方法都保存在自身类中,很明显single_method方法并不在str2的祖先链中, 那么single_method方法去哪了?下面的Eigenclass则告诉了我们答案.
Eigenclass
在obj上定义一个单件方法, 它存放在哪, 同样类是Class的对象, 而类方法不能被类的实例对象调用,说明类方法不在Class中,那么又存放在哪里呢?
当一个对象索要它的类时,Ruby并没有告诉我们全部,我们得到的类并不是看到的类,而是一个对象特有的隐藏类,我们称之为eigenclass.
- 1
- 2
- 3
- 4
- 5
- 6
在查找方法时,会先从接收者的eigenclass中查找,若未找到,则在eigenclass的超类中查找.
一个对象的eigenclass的超类是这个对象的类;一个类的eigenclass的超类是这个类的超类的eigenclass.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
当类包含模块时,它获得的是该模块的实例方法而不是类方法,类方法存在与模块的eigenclass中. 那么如何通过包含模块来定义类方法.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
my_method()方法是MyClass的eigenclass的一个实例方法,这样my_method()也是MyClass的一个类方法,这种技术称为类扩展.同样该技术运用在对象中则是对象扩展.
类宏
在Java中要想访问一个类的私有属性需要get和set方法,虽然Ruby对象并没有属性,但如果想像get和set一样访问,就会定义两个拟态方法.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这样的写法会给人很枯燥的感觉,我们可以通过Module#attr_*()方法家族中的成员来定义访问器.Module#attr_reader()可以生成一个读方法, Module#attr_writer()可以生成一个写方法,Module#attr_accessor()可以同时生成两者.
所有的attr_*()方法都定义在Module中,所以不过self是类还是模块,都可以使用它们.类似与attr_accessor()的方法我们称之为类宏, 虽然类宏看起来像关键字,但它们只是普通方法,只是可以用在类定义中.
方法别名
通过使用alias关键字,可以给Ruby方法取一个别名.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
环绕别名
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
上述代码虽然重写了length方法,但是别名方法还是引用的原始方法.
当重定义一个方法时,并没有真正修改这个方法,而是把当前存在的这个方法名与新定义的方法绑定起来, 只要旧方法还存在绑定的名字,仍然可以调用.旧的方法被新的方法所环绕,这种技巧称为环绕别名,步骤如下:.
1.给方法定义一个别名
2.重定义这个方法
3.在新的方法中调用老的方法
- Ruby元编程-学习笔记(四)-类定义
- Ruby元编程-学习笔记(四)-类定义
- Ruby 元编程 类定义
- Ruby 元编程 类定义
- ruby元编程——类定义
- Ruby元编程-学习笔记(二)-方法
- Ruby元编程-学习笔记(二)-方法
- 《Ruby 元编程》笔记
- Ruby元编程笔记一
- Ruby元编程笔记<一>
- Ruby元编程笔记<二>
- Ruby学习笔记之反射和元编程
- Ruby元编程-学习笔记(一)-对象模型
- Ruby元编程-学习笔记(三)-代码块
- Ruby元编程-学习笔记(一)-对象模型
- Ruby元编程-学习笔记(三)-代码块
- ruby学习笔记四
- ruby元编程4------类
- Ruby元编程-学习笔记(三)-代码块
- 关于linux常用命令
- git配置
- C# .NET Socket 简单实用框架
- HDU 1695 GCD
- Ruby元编程-学习笔记(四)-类定义
- 董的博客
- Android5.0 WebView中Http和Https混合问题
- 事件驱动模型概述
- Spring Boot执行repackage打包与Source must refer to an existing file异常解决
- Error:java: 无效的目标发行版: 1.8
- LayoutInflater源码分析
- Centos6.5安装docker
- 简谈JAVA基础--IO流