• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

关于类、模块的问题

发布: 2007-7-04 20:03 | 作者: admin | 来源:  网友评论 | 查看: 28次 | 进入软件测试论坛讨论

领测软件测试网 6.1 重定义类时,是否会覆盖原来的定义?

重定义同一个类时,意味着对原有定义进行补充,不会覆盖原来的定义。而重定义方法时,则会覆盖原有定义。

6.2 有类变量吗?

从1.6版本开始出现类变量。类变量名前都带有`@@'。

class Foo @@F = 0 def foo @@F += 1 print @@F, "\n" end end

在1.4以前的版本中,使用容器类(Array、Hash等)来代替类变量。

class Foo F = [0] def foo F[0] += 1 print F[0], "\n" end end 6.3 什么是类的实例变量?class Foo @a = 123 # (1) def foo p @a # (2) ... 123でなくnilになる。 end end

(1)是类的实例变量、(2)是通常的实例变量。(2)属于Foo类的实例,而(1)属于类对象Foo(Class的实例)。

不能在实例方法中直接访问类的实例变量。

因此上面的实例变量尚未初始化,其值为nil。

6.4 什么是特殊方法?

特殊方法是指某实例所特有的方法。

通常这么使用。

foo = Foo.new def foo.hello print "Hello\n" end foo.hello

若想向类中添加方法,却又不想生成子类时,可以使用特殊方法。

Java程序员可能会觉得它很像inner class。

6.5 什么是类方法?

类方法就是指类的特殊方法。上面我们提到,特殊方法是归属于某对象的方法,那么这里所说的“类的特殊方法”将作何解释呢?其实Ruby中有一个“元类”的概念。它是Class类的实例,同时又被所有的类所共有。类方法就定义在这个元类中。

从形式上看,将类名当作被调的方法就是类方法。

下面,我们就在Class类的Foo实例中添加一个特殊方法。

class Foo def Foo.test print "this is foo\n" end end

像这样来调用它。

Foo.test

您有没有注意到什么?

对了,这就是所谓的类方法。

当然了,Class中所定义的方法也可以用作类方法。

6.6 什么是特殊类?

上面我们提到了特殊方法。

简单说来,在Ruby中可以向对象(实例)中添加方法。

进一步讲,如果您想像操作类那样来操作对象时,该怎么办呢?

可千万别说您没这么想过(^^;

使用特殊类的话,您就可以做到这一点。

class Foo def hello print "hello.\n" end end foo = Foo.new foo.hello #=> hello. class << foo attr :name, true def hello print "hello. I'm ", @name, ".\n" end end foo.name = "Tom" foo.hello #=> hello. I'm Tom.

多棒呀。

好了,现在要问问题了

问题 如果不使用private_class_method的话,能不能将类方法变成private呢?

解答: 类方法就是类的特殊方法。

所以我们可以耍个小花招,这么处理它。

class Foo # ... end class << Foo def class_method print "class method\n" end private :class_method end Foo.class_method #=> Error

定义特殊方法时,既可以像上面这样在特殊类中加以定义,也可以直接使用def obj.method来完成定义。

另外,您还可以在模块中定义特殊方法(而且是private方法)。

6.7 什么是模块函数?

定义模块函数时,它们既是模块的特殊方法,同时又是private类型。例如,您既可以这样

Math.sqrt(2)

来调用它,又可以这样

include Math sqrt(2)

使用include来调用它,的确十分方便。

若您想把某方法定义成模块函数时,可以在模块定义中添加如下代码

module_function :method_name

即可完成定义。

6.8 类和模块有什么区别?

模块不能生成实例,而类不能被include。

6.9 模块可以生成子类吗?

在类(模块)中include模块之后,就可实现类似于多重继承的Mix-in功能。它与父类子类之间的这种直接继承关系有所不同,内含模块的类与该模块之间存在is_a?的关系。

6.10 在类定义中定义类方法 和 在顶层中定义类方法 之间有什么不同?

您在前者中可以直接使用常数,而在后者中则必须指定类名才行。

6.11 load和require有什么不同?

load只能加载用Ruby编写的源文件(*.rb)。

require还可以加载*.o文件。另外,一旦require某文件之后,即使再次require也不会进行加载。

加载路径也有所不同。

6.12 include和extend有什么不同?

include负责将module插入到类(模块)中,这样就能以函数的形式来调用方法;而extend负责将module插入到对象(实例)中,这样就添加了特殊方法。

6.13 self是什么?

self是指执行方法的主体本身。在函数形式的方法中,是把self当作被调的。

6.14 MatchData中的begin、end分别返回什么?

它们作用于$~,分别返回$0、$1等原来字符串的开始位置和终止位置。请参考展开标签中的例子。

6.15 如何使用类名来获得类?

如果我有classname = "SomeClass"时,如何生成SomeClass类的实例呢?主要有两个解决方法。

eval(classname).new Object.const_get(classname).new

第1种方法既简单又可以处理嵌套类(Net::HTTP等),但如果在CGI环境中滥用它的话,将十分危险。

而第2种方法却又无法处理嵌套类的问题。但如果进行以下处理的话,就可以处理嵌套类了。

# 如果只考虑Ruby 1.8之后的版本的话,可以这样 c = classname.split(/::/).inject(Object) {|c,name|
c.const_get(name) } c.new # 若想兼顾Ruby 1.6的话,则需要 c = Object classname.split(/::/).each do |name| c = c.const_get(name) end c.new

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网