關于類、模塊的問題

發表于:2007-07-04來源:作者:點擊數: 標簽:
6.1 重定義類時,是否會覆蓋原來的定義? 重定義同一個類時,意味著對原有定義進行補充,不會覆蓋原來的定義。而重定義方法時,則會覆蓋原有定義。 6.2 有類變量嗎? 從1.6版本開始出現類變量。類變量名前都帶有`@@'。 class Foo @@F = 0 def foo @@F += 1 pr
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

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97