一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Ruby - 進一步深入Ruby中的類與對象概念

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

2020-04-29 10:24腳本之家 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沒有應用實例和類變量的任何訪問控制權。

  1.     Public Methods: 任何人都可以被稱為public方法。方法默認為公用初始化,這始終是 private 除外。 .
  2.     Private Methods: private方法不能被訪問,或者甚至從類的外部瀏覽。只有類方法可以訪問私有成員。
  3.     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

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

延伸 · 閱讀

精彩推薦
  • Ruby剖析 Ruby 訪問控制

    剖析 Ruby 訪問控制

    前面,我們說 Ruby 沒有函數,只有方法.而且實際上有不止一種方法.這一節我們介紹 訪問控制 (accesscontrols). 想想當我們在最高層而不是在一個類的定義里定義...

    ruby教程網3572020-04-08
  • RubyRuby環境下安裝使用bundler來管理多版本的gem

    Ruby環境下安裝使用bundler來管理多版本的gem

    這篇文章主要介紹了Ruby環境下安裝使用bundler來管理多版本的gem的方法,舉了Ruby On Rails中的應用實例來進行演示,需要的朋友可以參考下 ...

    日拱一卒4332020-05-10
  • Ruby簡要說明Ruby中的迭代器

    簡要說明Ruby中的迭代器

    這篇文章主要介紹了Ruby中的迭代器,迭代器的概念在動態語言的編程中十分重要,文章中介紹了Ruby中的each迭代器和collect迭代器,需要的朋友可以參考下 ...

    goldensun2772020-04-25
  • RubyRuby設計模式編程中使用Builder建造者模式的實例

    Ruby設計模式編程中使用Builder建造者模式的實例

    這篇文章主要介紹了Ruby設計模式編程中使用Builder建造者模式的實例,建造者模式將一個復雜對象的構造與它的表示分離,使同樣的構建過程可以創建不同的表...

    范孝鵬2192020-05-07
  • RubyRuby進行文件信息輸出實例代碼

    Ruby進行文件信息輸出實例代碼

    Ruby進行文件信息輸出實例代碼,數據是隨機的,所以每次的記錄都會不同。 ...

    ruby教程網2962020-04-10
  • RubyRuby簡潔學習筆記(一):字符串、數字、類和對象

    Ruby簡潔學習筆記(一):字符串、數字、類和對象

    這篇文章主要介紹了Ruby簡潔學習筆記(一):字符串、數字、類和對象,本文是學習筆記第一篇,需要的朋友可以參考下 ...

    腳本之家2472020-04-20
  • RubyRuby迭代器的7種技巧分享

    Ruby迭代器的7種技巧分享

    這篇文章主要介紹了Ruby迭代器的7種技巧分享,Ruby中的迭代器非常人性化,本文既是講解了7個技巧也是講解了7種迭代器,需要的朋友可以參考下 ...

    腳本之家4782020-04-20
  • RubyCentOS中配置Ruby on Rails環境

    CentOS中配置Ruby on Rails環境

    經過一個上午的折騰,終于把ROR環境在CentOS中搞定,繞了很多彎路,把文章寫下來總結一下 ...

    可樂加糖4762020-04-12
主站蜘蛛池模板: 亚洲美色综合天天久久综合精品 | 久久黄色精品视频 | 黑人巨鞭大战白妞10级 | 国产一级网站 | 91精品手机国产露脸 | 人人揉人人爽五月天视频 | 国产欧美日韩成人 | 大伊香蕉精品二区视频在线 | 国产真实乱子伦xxxxchina | a级特黄毛片免费观看 | 九哥草逼网 | 国产欧美va欧美va香蕉在线观 | 男人的天堂久久精品激情a 男人的天堂va | 男女被爆动漫羞羞动漫 | 女同videos双性人 | 成人国产精品视频 | 91你懂的| 日韩成人在线视频 | 无码AV免费精品一区二区三区 | 国产麻豆精品免费视频 | 国产免费精彩视频 | 天生奶水1v1高h | 四虎2023| haodiaose在线精品免费观看 | 91传媒制片厂制作传媒破解版 | 操久| 色婷婷影院在线视频免费播放 | 啊皇上你好大要知画 | 91精品国产在线 | 出差上的少妇20p | 亚洲免费视频在线 | 欧美区视频 | 视频一区精品 | 91短视频破解版 | 色综合色狠狠天天综合色hd | 男模chinesegayxxxx | 四虎 2022 永久网站 | 亚洲第一人黄所 | 青青草成人在线观看 | 亚洲欧美成人综合 | 95视频免费看片 |