ruby是完全面向對象的,所有的數據都是對象,沒有獨立在類外的方法,所有的方法都在類中定義的。
一、類的定義語法
類的定義以 class 關鍵字開頭,后面跟類名,以 end標識符結尾。
類中的方法以 def關鍵字開頭,后面跟方法名及參數列表(如果有的話),以 end標識符結尾。
類也有構造函數,名字必須為initialize。
對象通過new來創建,new是類的方法。
舉例如下:
class Demo def initialize puts "begin create object" end def test puts "test" end end #創建對象,調用對象的方法 demo1= Demo.new demo1.test
上面的代碼先定義了一個類Demo ,類中定義了兩個分方法,這兩個方法均沒參數。
接着通過new來創建了一個對象,賦值給變量 demo1,最后調用 類的 test方法。
上面代碼運行的輸出信息是:
begin create object
test
二、類中的成員變量
類中有三種變量
1、一個是局部變量,在方法內 和方法的參數。這個就是普通的標識符定義即可。
2、類的實例變量。這個定義與其它語言有差別,需要以 @符號來標識。不能直接通過對象訪問,需要通過方法來訪問,相當於java中的private成員。
3、類變量,屬於類級別的,為類的所有對象所共享,需要以 @@符號來標識
三、類的實例變量
下面我們來看一個類的實例變量的例子:
class Demo def initialize(value) @a = value end def getA return @a end def setA(value) @a=value end end #創建對象,調用對象的方法 demo1= Demo.new(2) puts demo1.getA demo1.setA(10) puts demo1.getA
上面代碼創建的Demo類在構造函數中定義和初始化了一個實例變量 @a,並且定義了get和set方法來訪問實例變量。
在ruby中,無法直接在類的外部訪問實例變量,如 puts demo1.@a 這樣會報語法錯誤的。
對於實例變量,如果每次需要定義相應的 get 和 set方法,並且給通過get和set方法才能在外部訪問,這顯得比較啰嗦和麻煩。
ruby通過其元編程的特性可以簡化這些操作。具體我們來看下示例代碼:
class Demo attr_accessor:a def initialize(value) @a=value end end #創建對象,調用對象的方法 demo1= Demo.new(2) puts demo1.a demo1.a = 10 puts demo1.a
上面代碼通過 attr_accessor :a 就定義了一個實例變量 @a ,並在構造函數中對它初始化。
與上面 的區別是,外部可以直接通過對象變量訪問,但不能加 @符號,不過在類的方法內訪問需要加@符號。
可以看出,采用這種方式,省去了定義get和set方法,訪問起來更加簡潔。
設置attr_accessor,會自動對實例變量(如上面例子中的 @a),創建set和get方法。
對應的還有attr_reader只設置get方法,attr_writer只設置set方法。
class Demo attr_reader:a def initialize(value) @a=value end def set(value) @a = value puts @a end end #創建對象,調用對象的方法 demo1= Demo.new(2) demo1.set(10) puts demo1.a
如果定義成attr_reader,則在類的外部只能demo1.a來讀取變量信息,但不能 demo1.a = 2 這種方式來賦值(因為這實際調用的是set方法,而attr_reader不會產生set方法)。注意,這只影響外部訪問,類的內部方法使用沒有關系。
class Demo attr_writer:a def initialize(value) @a=value end def set(value) @a = value puts @a end def print puts @a end end #創建對象,調用對象的方法 demo1= Demo.new(2) demo1.a =20 demo1.print
從上面例子可以看出,定義成 attr_writer方式,在類的外部只能賦值,不能讀取(如這里的 puts demo1.a會報語法錯誤。).
同樣類的內部訪問不受影響。
需要說明的是,類的實例變量不一定先要在構造函數中定義和初始化。 可以在類的任意方法中定義和使用,使用前也不需要初始化。
如下面代碼:
class Demo def set(value) @a = value end def print puts @a end end #創建對象,調用對象的方法 demo1= Demo.new demo1.print demo1.set(10) demo1.print
如果在初始化之前就引用實例變量,則值為 nil (類似java中的null)。如上面代碼,創建對象后直接調用 print方法,在print方法中就引用了@a,而在這之前@a並未被定義和初始化,這不會報錯,只是這時@a的值為 nil.
可以看出,相對java, c++等傳統語言來說,ruby中類的實例變量的操作更加靈活和清晰。
