程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 進一步深入Ruby中的類與對象概念

進一步深入Ruby中的類與對象概念

編輯:更多關於編程

       這篇文章主要介紹了進一步深入Ruby中的類與對象概念,包括集成與多態等更多知識點的整理,需要的朋友可以參考下

      Ruby是純面向對象的語言,所有項目似乎要Ruby中為一個對象。Ruby中的每個值是一個對象,即使是最原始的東西:字符串,數字甚至true和false。即使是一個類本身是一個對象,它是Class類的一個實例。本章將通過所有功能涉及到Ruby的面向對象。

      類是用來指定對象的形式,它結合了數據表示和方法操縱這些數據,轉換成一個整齊的包。在一個類的數據和方法,被稱為類的成員。

      Ruby類的定義:

      定義一個類,定義的數據類型的草圖。 這實際上並不定義任何數據,但它定義的類名字的意思什麼,即是什麼類的對象將包括這樣一個對象上執行什麼操作可以。

      類定義開始與關鍵字class類名和 end 分隔。例如,我們定義Box類使用class關鍵字如下:

      class Box

      code

      end

      名稱必須以大寫字母開始,按照約定名稱中包含多個單詞,每個單詞沒有分隔符(駝峰式)一起執行。

      定義Ruby的對象:

      類為對象的藍圖,所以基本上是一個從一個類對象被創建。我們聲明一個類的對象使用new關鍵字。下面的語句聲明了兩個對象,Box 類:

      ?

    1 2 box1 = Box.new box2 = Box.new

      initialize方法:

      initialize方法是一個標准的Ruby類的方法,和其它面向對象編程語言的構造方法有相同的方式工作。 initialize方法是有用的,在創建對象的時候,一些類變量初始化。這種方法可能需要的參數列表,它像其他Ruby之前的方法用def關鍵字定義,如下所示:

      class Box

      def initialize(w,h)

      @width, @height = w, h

      end

      end

      實例變量:

      實例變量是類的一種屬性,一旦我們使用的類對象被創建的對象的屬性。每個對象的屬性被分別賦值的並與其它對象共享,它們在類的內部使用@操作符訪問,但訪問類之外的,我們使用的公共方法被稱為訪問器方法。如果我們把上述定義的類 Box,然後 @width 和 @height 類 Box實例變量。

      ?

    1 2 3 4 5 6 class Box def initialize(w,h) # assign instance avriables @width, @height = w, h end end

      訪問器和setter方法:

      為了外部能訪問類的變量,它們必須定義存取器方法,這些存取器方法也被稱為getter方法。下面的例子演示了如何使用訪問器方法:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #!/usr/bin/ruby -w   # define a class class Box # constructor method def initialize(w,h) @width, @height = w, h end   # accessor methods def printWidth @width end   def printHeight @height end end   # create an object box = Box.new(10, 20)   # use accessor methods x = box.printWidth() y = box.printHeight()   puts "Width of the box is : #{x}" puts "Height of the box is : #{y}"

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 2 Width of the box is : 10 Height of the box is : 20

      類似的存取方法用於訪問的變量值,Ruby提供了一種方法來從類的外部設置這些變量的值,那就是setter方法??,定義如下:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #!/usr/bin/ruby -w   # define a class class Box # constructor method def initialize(w,h) @width, @height = w, h end   # accessor methods def getWidth @width end def getHeight @height end   # setter methods def setWidth=(value) @width = value end def setHeight=(value) @height = value end end   # create an object box = Box.new(10, 20)   # use setter methods box.setWidth = 30 box.setHeight = 50   # use accessor methods x = box.getWidth() y = box.getHeight()   puts "Width of the box is : #{x}" puts "Height of the box is : #{y}"

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 2 Width of the box is : 30 Height of the box is : 50

      實例方法:

      也以同樣的方式,因為我們使用def關鍵字定義其他方法,並按下圖所示僅對使用一個類的實例,它們可以被用來定義該實例方法。它們的功能不局限於訪問實例變量,他們也可以按要求做更多的事情。

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #!/usr/bin/ruby -w   # define a class class Box # constructor method def initialize(w,h) @width, @height = w, h end # instance method def getArea @width * @height end end   # create an object box = Box.new(10, 20)   # call instance methods a = box.getArea() puts "Area of the box is : #{a}"

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 Area of the box is : 200

      類的方法和變量:

      類變量是一個變量,這是一個類的所有實例之間共享。該變量是一個實例,它是可訪問對象實例。兩個@字符類變量帶有前綴(@@)。在類定義類變量必須初始化,如下所示。

      類方法的定義使用:def self.methodname() 以 end 字符結束,將被稱為使用classname.methodname類名,在下面的例子所示:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #!/usr/bin/ruby -w   class Box # Initialize our class variables @@count = 0 def initialize(w,h) # assign instance avriables @width, @height = w, h   @@count += 1 end   def self.printCount() puts "Box count is : #@@count" end end   # create two object box1 = Box.new(10, 20) box2 = Box.new(30, 100)   # call class method to print box count Box.printCount()

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 Box count is : 2

      to_s 方法:

      所定義的任何類的實例應該有一個 to_s 方法返回一個字符串形式表示對象。下面以一個簡單的例子來表示一個Box對象,在寬度和高度方面:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!/usr/bin/ruby -w   class Box # constructor method def initialize(w,h) @width, @height = w, h end # define to_s method def to_s "(w:#@width,h:#@height)" # string formatting of the object. end end   # create an object box = Box.new(10, 20)   # to_s method will be called in reference of string automatically. puts "String representation of box is : #{box}"

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 String representation of box is : (w:10,h:20)

      訪問控制:

      Ruby提供了三個級別的保護實例方法的級別:public, private 和 protected。 Ruby沒有應用實例和類變量的任何訪問控制權。

      Public Methods: 任何人都可以被稱為public方法。方法默認為公用初始化,這始終是 private 除外。 .

      Private Methods: private方法不能被訪問,或者甚至從類的外部浏覽。只有類方法可以訪問私有成員。

      Protected Methods: 受保護的方法可以被調用,只能通過定義類及其子類的對象。訪問保存在類內部。

      以下是一個簡單的例子來說明三個訪問修飾符的語法:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #!/usr/bin/ruby -w   # define a class class Box # constructor method def initialize(w,h) @width, @height = w, h end   # instance method by default it is public def getArea getWidth() * getHeight end   # define private accessor methods def getWidth @width end def getHeight @height end # make them private private :getWidth, :getHeight   # instance method to print area def printArea @area = getWidth() * getHeight puts "Big box area is : #@area" end # make it protected protected :printArea end   # create an object box = Box.new(10, 20)   # call instance methods a = box.getArea() puts "Area of the box is : #{a}"   # try to call protected or methods box.printArea()

      當上面的代碼被執行時,產生下面的結果。在這裡,第一種方法被調用成功,但第二種方法給一個提示。

      ?

    1 2 3 Area of the box is : 200 test.rb:42: protected method `printArea' called for # <Box:0xb7f11280 @height=20, @width=10> (NoMethodError)

      類的繼承:

      在面向對象的編程中最重要的概念之一是繼承。繼承允許我們定義一個類在另一個類的項目,這使得它更容易創建和維護應用程序。

      繼承也提供了一個機會,重用代碼的功能和快速的實現時間,但不幸的是Ruby不支持多級的繼承,但Ruby支持混入。一個mixin繼承多重繼承,只有接口部分像一個專門的實現。

      當創建一個類,而不是寫入新的數據成員和成員函數,程序員可以指定新的類繼承現有類的成員。這種現有的類稱為基類或父類和新類稱為派生類或子類。

      Ruby也支持繼承。繼承和下面的例子解釋了這個概念。擴展類的語法很簡單。只需添加一個<字符的超類聲明的名稱。例如,定義Box類的子類classBigBox:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #!/usr/bin/ruby -w   # define a class class Box # constructor method def initialize(w,h) @width, @height = w, h end # instance method def getArea @width * @height end end   # define a subclass class BigBox < Box   # add a new instance method def printArea @area = @width * @height puts "Big box area is : #@area" end end   # create an object box = BigBox.new(10, 20)   # print the area box.printArea()

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 Big box area is : 200

      方法重載:

      雖然可以在派生類中添加新的函數,但有時想改變的行為已經在父類中定義的方法。只需通過保持相同的方法名和重寫該方法的功能,如下圖所示,在這個例子可以這樣做:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #!/usr/bin/ruby -w   # define a class class Box # constructor method def initialize(w,h) @width, @height = w, h end # instance method def getArea @width * @height end end   # define a subclass class BigBox < Box   # change existing getArea method as follows def getArea @area = @width * @height puts "Big box area is : #@area" end end   # create an object box = BigBox.new(10, 20)   # print the area using overriden method. box.getArea()

      運算符重載:

      我們想“+”運算符使用+,*操作由一個標量乘以一箱的寬度和高度,這裡是一個版Box類的定義及數學運算符:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Box def initialize(w,h) # Initialize the width and height @width,@height = w, h end   def +(other) # Define + to do vector addition Box.new(@width + other.width, @height + other.height) end   def -@ # Define unary minus to negate width and height Box.new(-@width, -@height) end   def *(scalar) # To perform scalar multiplication Box.new(@width*scalar, @height*scalar) end end

      凍結對象:

      有時候,我們要防止被改變的對象。凍結對象的方法可以讓我們做到這一點,有效地把一個對象到一個恆定。任何對象都可以被凍結通過調用Object.freeze。不得修改凍結對象:不能改變它的實例變量。

      可以使用Object.frozen?語句檢查一個給定的對象是否已經被凍結,被凍結的情況下的對象語句方法返回true,否則返回false值。下面的示例 freeze 的概念:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #!/usr/bin/ruby -w   # define a class class Box # constructor method def initialize(w,h) @width, @height = w, h end   # accessor methods def getWidth @width end def getHeight @height end   # setter methods def setWidth=(value) @width = value end def setHeight=(value) @height = value end end   # create an object box = Box.new(10, 20)   # let us freez this object box.freeze if( box.frozen? ) puts "Box object is frozen object" else puts "Box object is normal object" end   # now try using setter methods box.setWidth = 30 box.setHeight = 50   # use accessor methods x = box.getWidth() y = box.getHeight()   puts "Width of the box is : #{x}" puts "Height of the box is : #{y}"

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 2 3 Box object is frozen object test.rb:20:in `setWidth=': can't modify frozen object (TypeError) from test.rb:39

      類常量:

      可以在類裡定義分配一個直接的數字或字符串值,而不使用其定義一個變量為@@ 或 @。按照規范,我們保持常量名大寫。

      一個常量一旦被定義就不能改變它的值,但可以在類裡像常量一樣直接訪問,但如果要訪問一個類之外的常量,那麼要使用類名::常量,所示在下面的例子。

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/usr/bin/ruby -w   # define a class class Box BOX_COMPANY = "TATA Inc" BOXWEIGHT = 10 # constructor method def initialize(w,h) @width, @height = w, h end # instance method def getArea @width * @height end end   # create an object box = Box.new(10, 20)   # call instance methods a = box.getArea() puts "Area of the box is : #{a}" puts Box::BOX_COMPANY puts "Box weight is: #{Box::BOXWEIGHT}"

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 2 3 Area of the box is : 200 TATA Inc Box weight is: 10

      類常量繼承和實例方法一樣,可以覆蓋。

      創建對象使用分配:

      當創建一個對象,而不調用它的構造函數初始化,即可能有一個情況:采用 new 方法,在這種情況下可以調用分配,這將創造一個未初始化的對象,看下面的例子:

      ?

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #!/usr/bin/ruby -w   # define a class class Box attr_accessor :width, :height   # constructor method def initialize(w,h) @width, @height = w, h end   # instance method def getArea @width * @height end end   # create an object using new box1 = Box.new(10, 20)   # create another object using allocate box2 = Box.allocate   # call instance method using box1 a = box1.getArea() puts "Area of the box is : #{a}"   # call instance method using box2 a = box2.getArea() puts "Area of the box is : #{a}"

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 2 3 4 5 Area of the box is : 200 test.rb:14: warning: instance variable @width not initialized test.rb:14: warning: instance variable @height not initialized test.rb:14:in `getArea': undefined method `*' for nil:NilClass (NoMethodError) from test.rb:29

      類信息:

      如果類定義的可執行代碼,這意味著他們在執行的上下文中一些對象:自身都必須引用的東西。讓我們來看看它是什麼。

      ?

    1 2 3 4 5 6 7 #!/usr/bin/ruby -w   class Box # print class information puts "Type of self = #{self.type}" puts "Name of self = #{self.name}" end

      當上面的代碼執行時,它會產生以下結果:

      ?

    1 2 Type of self = Class Name of self = Box

      這意味著,一個類的定義,作為當前對象的類並執行。在元類和其超類的方法將在執行過程中使用的方法定義。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved