類是面向?qū)ο笾幸粋€重要的術(shù)語。我們可以把類看作是對象的抽象,
所有的這類對象都有這些特征。而對象則是類的具體實(shí)現(xiàn),按照類的要求創(chuàng)建的
對象就是該類的對象。類就像對象的雛形一樣,決定了對象的行為。
eg:用數(shù)組類創(chuàng)建數(shù)組對象
arr=Array.new #[]
用class方法查看對象屬于那個類
arr=[1,2,3]p arr.class #Arrayp Array.class #Class
所有的類都是Class類的對象。
當(dāng)判斷某個對象是否屬于某個類,我們可以使用instance_of?方法。
arr=[1,2,3]p arr.instance_of? Array #truep arr.instance_of? Object #false
繼承
通過擴(kuò)展已經(jīng)創(chuàng)建的類來創(chuàng)建新的類成為繼承。繼承后創(chuàng)建的新類被稱為子類。
被繼承的類稱為父類。
BasicObject類是ruby中所有類的父類。他定義了作為ruby對象最基本的功能。
Object是BasicObject的子類。定義一般類所需要的功能。
根據(jù)類的反向繼承關(guān)系追查對象是否屬于某個類,則可以使用is_a?方法。
arr=[1,2,3]p arr.is_a? Array #truep arr.is_a? Object #true
創(chuàng)建類
class 類名 類的定義end
類名的首字母必須大寫.eg:
class Sayhello def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#實(shí)例化對象java=Sayhello.new("java")ruby=Sayhello.new
調(diào)用new方法創(chuàng)建對象時會默認(rèn)調(diào)用initialize方法。
@name時實(shí)例變量。hello方法時實(shí)例方法。實(shí)例方法中可以直接引用實(shí)例變量。
引用未定義的實(shí)例變量會返回nil.
存取器
ruby中不能直接訪問實(shí)例變量或?qū)?shí)例變量賦值。需要通過方法來操作。
class Sayhello def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" end #獲取實(shí)例變量的方法 def name puts "獲取實(shí)例變量@name" @name end #修改實(shí)例變量的方法 def name=(value) puts "修改實(shí)例變量@name" @name=value endend#實(shí)例化對象java=Sayhello.new("java") #調(diào)用initialize方法p java.name #調(diào)用name方法java.name="python" #調(diào)用name=方法p java.name #調(diào)用name方法java.hello #調(diào)用hello方法
Ruby提供了更簡便的實(shí)現(xiàn)方法
定義 | 意義 |
---|---|
attr_reader :name | 只讀(定義name方法) |
attr_writer :name | 只寫(定義name=方法) |
attr_accessor :name | 讀寫(定義上面的兩個方法) |
eg:
class Sayhello #name和name= attr_accessor :name def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#實(shí)例化對象java=Sayhello.new("java") #調(diào)用initialize方法p java.name #"java"java.name="python"p java.name #"python"java.hello #hell0,I am python
特殊變量self
在類內(nèi)部self指向類自身,在實(shí)例方法內(nèi)部,self指向調(diào)用方法的實(shí)例。
class Sayhello #name和name= attr_accessor :name def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{self.name}!" endend#實(shí)例化對象java=Sayhello.new("java") #調(diào)用initialize方法java.hello #hell0,I am java
等價于
class Sayhello #name和name= attr_accessor :name def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#實(shí)例化對象java=Sayhello.new("java") #調(diào)用initialize方法java.hello #hell0,I am java
類方法
class Sayhello class << Sayhello def hello(name) puts "#{name} said hello." end end def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#實(shí)例化對象java=Sayhello.new("java") #調(diào)用initialize方法java.hello #hell0,I am java#調(diào)用類方法Sayhello.hello "ruby" #ruby said hello;
在類內(nèi)部定義類方法
class Sayhello class << self def hello(name) puts "#{name} said hello" end end def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#調(diào)用類方法Sayhello.hello "ruby" #ruby said hello
或者
class Sayhello def Sayhello.hello(name) puts "#{name} said hello" end def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#調(diào)用類方法Sayhello.hello "ruby" #ruby said hello
或者
class Sayhello def self.hello(name) puts "#{name} said hello" end def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#調(diào)用類方法Sayhello.hello "ruby" #ruby said hello
使用class <<類名 ~ end 這種寫法的類定義稱為單例類定義。
單例類定義中定義的方法稱為單例類方法。
常量
class語句中可以定義常量
class Sayhello Version="1.0" def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello puts "hello,I am #{@name}!" endend#實(shí)例化對象p Sayhello::Version #"1.0"
類變量
類變量為所有類的實(shí)例所共享,從類的外部訪問類變量時需要存儲器,不能使用
attr_accessor等,需要直接定義。
class Sayhello @@count=0 def Sayhello.count @@count end def initialize(myname="ruby") puts "調(diào)用我實(shí)例化對象" @name=myname end def hello @@count+=1 puts "hello,I am #{@name}!" endend#實(shí)例化對象p Sayhello.count #0ruby=Sayhello.newruby.hellojava=Sayhello.new "java"java.hellop Sayhello.count #2
限制方法的調(diào)用
Ruby提供了三種方法的訪問級別:
關(guān)鍵字 | 訪問級別 |
---|---|
public | 以實(shí)例方法的形式向外公開該方法 |
private | 只在類內(nèi)部可以用 |
protected | 類內(nèi)部及子類中可以使用 |
eg:
class AccTest def pub puts "hello" end #設(shè)置方法的訪問權(quán)限 public :pub def priv puts "private" end #設(shè)置方法的訪問權(quán)限 private :privendacc=AccTest.newacc.pubacc.priv #NoMethodError
希望統(tǒng)一定義多個方法的訪問級別時??梢允褂孟旅娴恼Z法。
eg:
class AccTest public #以下的方法都被定義為public def pub puts "hello" end private #以下方法都被定義為private def priv puts "private" endendacc=AccTest.newacc.pubacc.priv #NoMethodError
沒有定義訪問訪問級別方法默認(rèn)為public,但是initialize方法是個例外,
他通常被定義為private.
擴(kuò)展類
eg:在原有的類的基礎(chǔ)上添加方法
class String def count_word #用空格分割self ary=self.split(/\s+/) #返回分解后的數(shù)組的長度 return ary.size endendstr="I am ruby"p str.count_word #3
繼承
class 類名 < 父類名 類定義end
eg:RingArray繼承Array
class RingArray < Array #重定義運(yùn)算符[] def[](i) ind=i%self.size super(ind) endendarr=RingArray["金","木","水","火","土"]p arr[6] #"木"p arr[12] #"水"
定義類的時候沒有指定父類的情況下,ruby會默認(rèn)該類為Object類的子類。
有時候我們希望繼承更輕量級的類,就會使用BasicObject類
eg:查看類的實(shí)例方法
p Object.instance_methodsp BasicObject.instance_methods #[:!, :==, :!=, :__send__, :equal?, :instance_eval, :instance_exec, :__id__]
需要繼承BasicObject類,需要顯式的繼承。
alias與undef
使用alias給方法設(shè)置別名.或者在重定義已經(jīng)存在的方法時,為了使用別名調(diào)用
原來的方法,也需要用到alias.
alias 別名 原名alias :別名 :原名
class Sayhello def hello "hello" end alias sayhello helloendh=Sayhello.newp h.sayhello #"hello"
eg:
class Sayhello def hello "hello" end alias sayhello helloendclass Child < Sayhello alias old_hello hello def hello "#{old_hello},again." endendchild=Child.newp child.old_hello #"hello"p child.hello #"hello,again."
undef
undef用于刪除已定義的方法。
undef 方法名undef :方法名
eg:子類中刪除父類定義的方法
class Sayhello def hello "hello" end alias sayhello hello def del "delete" endendclass Child < Sayhello alias old_hello hello def hello "#{old_hello},again." end undef delendchild=Child.newp child.old_hello #"hello"p child.hello #"hello,again."p child.del #NoMethodError
單例類
利用單例類給對象添加方法
str1="Ruby"str2="Ruby"class << str1 def hello "hello,#{self}!" endendp str1.hello #"hello,Ruby!"p str2.hello #(NoMethodError)
Ruby中所有的類都是Class類的對象,因此,Class對象的實(shí)例方法以及
類對象的單例方法都是類方法。