Groovy高效编程:动态改变对象的能力

从Groovy1.1beta-2开始,实现动态改变对象的能力变的十分简单:

一开始,我们有这样一个类:

class Person {
String name
}

该类的实例都是哑巴,不能说话,作为造物主的我们该完善它们,使它们能自我介绍(添加实例方法):class Person {
String name
}
// 添加自我介绍的行为
Person.metaClass.introduce << {println "I'm $name"}

现在让我们看看,它们到底是否真的能够开口自我介绍了呢:

class Person {
String name
}
   // 添加自我介绍的行为
Person.metaClass.introduce << {println "I'm $name"}
def person = new Person(name:"山风小子")
person.introduce()

运行结果:

I'm 山风小子

嗯~人类改造成功~

但人应该有性别吧,嗯~对的,加个性别属性sex(添加属性):

class Person {
String name
}
// 添加自我介绍的行为
Person.metaClass.introduce << {println "I'm $name"}
// 添加性别属性,默认为男(Male)
Person.metaClass.sex = "Male"
def person = new Person(name:"山风小子")
person.introduce()
println person.sex 

运行结果:

I'm 山风小子

Male

时间: 2024-10-10 14:40:21

Groovy高效编程:动态改变对象的能力的相关文章

《C++面向对象高效编程(第2版)》——1.8 深入了解对象

1.8 深入了解对象 C++面向对象高效编程(第2版) 如前所述,对象是类的实例,对象赋予类生命.换言之,可以通过实例化一个对象,并对其进行操作,体验类可以完成的功能.对象很聪明,它知道可以做什么,不可以做什么.另外,对象还知道如何修改和维护它的数据成员. 因此,区别类和对象是一个逻辑问题.简单地说,对象是带有状态和行为的活的实体.所有类对象的行为都定义在类中,而状态则由对象单独维护.状态和行为这两个词非常简单,但应用于对象上却意义深远. 1.8.1 对象的状态 为了讨论对象的状态,我们再回顾一

《C++面向对象高效编程(第2版)》——4.4 对象的标识

4.4 对象的标识 C++面向对象高效编程(第2版)本节将介绍命名对象的概念.特别地,我们要明辨对象的名称.对象的标识和对象间共享的语义. 对于这个例子(见图4-4),回顾TPerson类.以下一段代码创建了一些TPerson类对象. 图4-4 main() { TPerson person0("Albert Einstein", 0, 0, "12-11-1879"); TPerson person1("12-11-1879"); TPerso

《C++面向对象高效编程(第2版)》——4.6 对象赋值的语义

4.6 对象赋值的语义 C++面向对象高效编程(第2版) 赋值与复制的操作非常类似.在C++中,绝大多数的复制操作都由语言隐式调用(当对象按值传递或按值返回时).当通过现有对象创建新对象时,也进行了复制操作(但不是很频繁).与复制相反的是,赋值是必须由程序员显式调用的操作.然而,在Eiffel和Smalltalk中,赋值和复制操作都由程序员显式调用.这也是基于值的语言与基于引用的语言之间的区别. 在C++中,对于对象和基本类型赋值都具有相同的含义.把基本类型变量赋值给另一个(兼容的)基本类型变量

《C++面向对象高效编程(第2版)》——4.7 对象相等的语义

4.7 对象相等的语义 C++面向对象高效编程(第2版)显然,赋值和复制是类的设计者和实现者必须考虑的重要问题.另一个相关问题也同等重要,即对象相等(object equality)的概念. 当我们说两个对象相等时,即一个对象和另一个对象相等到底意味着什么?要牢记,两个不同对象相等和两个名称代表相同对象(也就是对象之间等价的概念),这两个概念是有区别的.对象相等要比较对象的结构和状态,而对象等价(object equivalence)则要比较对象的地址.两个不同的对象可能相等,但是不允许它们是同

C#编程实现动态改变配置文件信息的方法_C#教程

本文实例讲述了C#编程实现动态改变配置文件信息的方法.分享给大家供大家参考,具体如下: 配置文件实际上就是一个XML文件,所以我们可以使用XmlDocument来进行操作. 代码如下: static void Main(string[] args) { XmlDocument xDoc = new XmlDocument(); xDoc.Load("../../App.config");//加载xml文件 XmlNode xNode; XmlElement xElem1; XmlEle

《C++面向对象高效编程(第2版)》——2.2 对象接口的重要性

2.2 对象接口的重要性 C++面向对象高效编程(第2版)数据抽象的目的是,提供清晰和充足的接口,在方便且受控的模式下允许用户访问底层实现.接口应满足用户使用对象的基本需求.我们的唯一目标是:牢记客户,为让她们的生活更加舒适而不懈努力.因此,抽象的首要目标是,为客户简化操作. 2.2.1 什么是充足的接口 仅为讨论需要,假定我们设计的LD播放机未提供STOP按钮,会怎样?它将永远播放一张碟片!只有切断电源才能让播放机停止播放.可见,没有STOP按钮的接口不足以满足用户的基本要求.大多数情况下,如

《C++面向对象高效编程(第2版)》——2.12 类中的访问区域

2.12 类中的访问区域 C++面向对象高效编程(第2版)每个类都有3个不同的访问区域.在我使用过的所有OOP语言中,只有C++精心设计了这3个区域. public区域是最重要的区域,为类的用户指定了类的接口.任何客户都可以访问public区域. 本书的源代码样式 (1)所有的类名都以T开始.类的行为与在语言中添加的新类型类似,因此使用前缀T 1.但是,在表示实现这些类的文件名时,去掉T.例如,包含TInt接口的文件名是Int.h. (2)所有的成员函数名,首字母大写(如Add().FlipSl

《C++面向对象高效编程(第2版)》——3.3 复制构造函数

3.3 复制构造函数 C++面向对象高效编程(第2版)③ TIntStack s2 = s1;这是一个小小的技巧.我们试图创建TIntStack类的另一个对象s2.但是,我们希望用s1初始化这个对象.换句话说,必须通过s1创建s2.当然,前提是s1已经存在.这类似于以下声明: int j; int k = j; // 创建一个k并初始化为j``` 在这种情况下,编译器知道如何用j初始化k,因为int是语言定义(内置)类型.然而,③中的TIntStack是程序员定义类型,这表明由程序员负责将s1初

《C++面向对象高效编程(第2版)》——4.2 无用单元收集问题

4.2 无用单元收集问题 C++面向对象高效编程(第2版) 在我们讨论无用单元收集1(garbage collection)之前,先了解一下何为无用单元(garbage),何为悬挂引用(dangling reference). 4.2.1 无用单元 所谓无用单元(garbage),是一块存储区(或资源),该存储区虽然是程序(或进程)的一部分,但是在程序中却不可再对其引用.按照C++的规定,我们可以说,无用单元是程序中没有指针指向的某些资源.以下是一个示例: main() { char* p =