第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Ruby 的類(lèi)

我們?cè)谥暗恼鹿?jié)講了 Ruby 的很多對(duì)象,學(xué)會(huì)了如何使用簡(jiǎn)單的對(duì)象(例如:數(shù)字和字符串)以及數(shù)據(jù)結(jié)構(gòu)數(shù)組和哈希來(lái)完成一些工作,了解如何使用方法,做好了充足的準(zhǔn)備。本章中,我會(huì)為大家講解 Ruby 的類(lèi),如何創(chuàng)建一個(gè)類(lèi)以及類(lèi)的實(shí)例,以及類(lèi)的實(shí)例方法如何創(chuàng)建。

1. 什么是 Ruby 的類(lèi)

當(dāng) Ruby 運(yùn)行程序的時(shí)候,會(huì)創(chuàng)建一個(gè)空間,我們使用具體的事物對(duì)這些空間進(jìn)行填充,我們可以調(diào)用這些事物的方法去做某些事情。同時(shí),每個(gè)具體的事物(對(duì)象)都是一般思想或類(lèi)型的實(shí)例,這些思想稱(chēng)為類(lèi)。

在終端中我們可以通過(guò)class方法來(lái)查看對(duì)象所屬的類(lèi)。

實(shí)例:

"Hello World".class

# ---- 輸出結(jié)果 ----
String

對(duì)象是類(lèi)的具體實(shí)例(表現(xiàn))。

我們還可以使用is_a?的方法來(lái)具體詢(xún)問(wèn)對(duì)象是否屬于某個(gè)類(lèi):

實(shí)例:

"Hello World".is_a?(String)

# ---- 輸出結(jié)果 ----
true

類(lèi)是用于對(duì)象的藍(lán)圖。類(lèi)具有很多特性,每個(gè)類(lèi)定義了許多方法,這些方法特定用于此類(lèi)事物(例如:字符串),每次從類(lèi)創(chuàng)建對(duì)象的時(shí)候,每個(gè)對(duì)象都會(huì)擁有類(lèi)給他們的這些方法,也可以說(shuō),對(duì)象從類(lèi)繼承了方法。

2. 一步一步創(chuàng)建類(lèi)

2.1 定義一個(gè)類(lèi)

首先讓我們創(chuàng)建一個(gè)Calculator的類(lèi),并逐步為它添加方法。

實(shí)例:

class Calculator
end

解釋:我們使用關(guān)鍵字class,名稱(chēng)和關(guān)鍵字end定義一個(gè)類(lèi)。

注意事項(xiàng):我們定義類(lèi)的時(shí)候,首字母一定要大寫(xiě)開(kāi)頭,否則會(huì)出現(xiàn)報(bào)錯(cuò)。同樣對(duì)于由幾個(gè)單詞命名的類(lèi),我們應(yīng)該使用大寫(xiě)字母分隔這些單詞,例如:RubyStudyGroup,而對(duì)于變量名和方法名,我們要使用下劃線(xiàn),且所有內(nèi)容都應(yīng)該小寫(xiě),例如:local_variable,method_name。

2.2 創(chuàng)建一個(gè)實(shí)例

因?yàn)槲覀兌x了一個(gè)完整的有效類(lèi),所以我們可以創(chuàng)建一個(gè)Calculator實(shí)例,下面是創(chuàng)建一個(gè)Calculator實(shí)例的方法。

Calculator.new

# ---- 輸出結(jié)果 ----
#<Calculator:0x00007fb4132c0af0>

解釋new方法是在類(lèi)Calculator上定義的(Calculator它本身既是一個(gè)類(lèi)也是一個(gè)對(duì)象,還記得我們說(shuō)Ruby中所有東西都是對(duì)象嗎。所以它也可以擁有方法)。此方法創(chuàng)建了一個(gè)新的實(shí)例,并返回它。

格式#<...>告訴您此對(duì)象不是簡(jiǎn)單的東西,比如數(shù)字,字符串或數(shù)組。它只是告訴您類(lèi)的名稱(chēng),Calculator以及Ruby分配給該對(duì)象的內(nèi)部ID。

每個(gè)對(duì)象都有自己唯一的內(nèi)部對(duì)象ID,當(dāng)我在計(jì)算機(jī)上運(yùn)行此代碼時(shí),Ruby分配的ID為0x00007fb4132c0af0。如果您運(yùn)行它,將會(huì)得到不同的結(jié)果。實(shí)際上,在大多數(shù)情況下,您可以忽略此ID。另外,我們可以檢查我們的新計(jì)算器實(shí)例確實(shí)是類(lèi)Calculator的實(shí)例。

實(shí)例:

class Calculator
end
calculator = Calculator.new
puts calculator.class
puts calculator.is_a?(Calculator)

# ---- 輸出結(jié)果 ----
Calculator
true

2.3 定義實(shí)例方法

我們可以在類(lèi)和對(duì)象上定義和調(diào)用方法。類(lèi)上可用的方法稱(chēng)為類(lèi)方法,實(shí)例上可用的方法稱(chēng)為實(shí)例方法。剛才我們定義了一個(gè)類(lèi),現(xiàn)在讓我們?yōu)樗黾右粋€(gè)sum方法。

實(shí)例:

class Calculator
  def sum(number, other)
    number + other
  end
end

解釋:我們?cè)陬?lèi)中定義一個(gè)方法,即為這個(gè)類(lèi)的實(shí)例方法。

注意事項(xiàng):我們?cè)诙x實(shí)例方法的時(shí)候記得要縮進(jìn) 2 個(gè)空格,表明sum屬于Calculator類(lèi)。這是一種規(guī)范。

那么我們?nèi)绾问褂眠@個(gè)定義的sum實(shí)例方法呢?

我們可以實(shí)例化一個(gè)Calculator,然后調(diào)用這個(gè)方法。

實(shí)例:

calculator = Calculator.new
puts calculator.sum(2, 3)

# ---- 輸出結(jié)果 ----
5

2.4 初始化對(duì)象

在我們向類(lèi)添加任何行為(方法)之前,我們希望能夠?yàn)槠涮峁┮恍┏跏紨?shù)據(jù)。

讓我們重新定義一個(gè)Person類(lèi)。

實(shí)例:

class Person
end

在我們的情況下,我們希望該人知道自己的名字。

實(shí)例:

class Person
  def initialize(name)
  end
end

解釋:您會(huì)看到我們?yōu)檫@個(gè)類(lèi)增加了一個(gè)名為initialize的方法,并且可以接收一個(gè)name參數(shù)。當(dāng)類(lèi)方法new創(chuàng)建對(duì)象時(shí),將在內(nèi)部調(diào)用特殊的initialize方法。

我們可以通過(guò)以下這種方式將名稱(chēng)傳遞給類(lèi)的內(nèi)部:

p Person.new("Andrew")

# ---- 輸出結(jié)果 ----
#<Person:0x00007fb41326b118>

2.5 使用實(shí)例變量記錄初始化屬性

繼續(xù)我們剛才做的事,我們想在實(shí)例化對(duì)象的時(shí)候,讓對(duì)象保留自己初始化的名稱(chēng),這時(shí)我們用到了實(shí)例變量instance variable

實(shí)例:

class Person
  def initialize(name)
    @name = name
  end
end

解釋:我們將name的值賦予了實(shí)例變量@name,它的作用域?yàn)檎麄€(gè)在對(duì)象范圍內(nèi)的任何位置。

此時(shí)我們?cè)俅螌?shí)例化Person類(lèi):

p Person.new("Andrew")

#---- 輸出結(jié)果 ----
#<Person:0x00007fb41321add0 @name="Andrew">

此時(shí),我們創(chuàng)建的Person對(duì)象中有了一個(gè)實(shí)例變量@name,它的值為Andrew。

2.6 屬性讀取器(getter)

我們已經(jīng)創(chuàng)建了一個(gè)名為 Andrew 的Person對(duì)象,那么如何獲取它的名字呢。

實(shí)例:

class Person
  def initialize(name)
    @name = name
  end
  
  def name
    @name
  end
end

此時(shí)我們可以通過(guò)向?qū)ο蟀l(fā)送name的消息,獲取對(duì)應(yīng)的信息。

實(shí)例:

person = Person.new("Andrew")
person.name

#---- 輸出結(jié)果 ----
"Andrew"

解釋:我們定義了一個(gè)方法name,它返回了實(shí)例變量@name,由此創(chuàng)建了一個(gè)屬性讀取器。屬性讀取器返回實(shí)例變量的值,也可以說(shuō),屬性讀取器公開(kāi)了實(shí)例變量,讓所有的人都可以讀取它。

除此之外我們還有一種簡(jiǎn)單的寫(xiě)法,實(shí)現(xiàn)@name的讀取:

class Person
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

和上面的操作是等效的。

2.7 屬性設(shè)置器(setter)

現(xiàn)在我們添加一個(gè)功能,一個(gè)人不僅要有名稱(chēng),也要能設(shè)置密碼,這個(gè)密碼我們希望在Person對(duì)象被實(shí)例后才被告知,讓我們進(jìn)一步改變這個(gè)類(lèi)。

class Person
  def initialize(name)
    @name = name
  end

  def name
    @name
  end

  def password=(password)
    @password = password
  end
end

解釋:如您所見(jiàn),方法password =只能執(zhí)行一個(gè)參數(shù)(稱(chēng)為password),并將此局部變量的值分配給實(shí)例變量@password,其他什么也不做。

現(xiàn)在讓我們?yōu)橐粋€(gè)Person對(duì)象添加密碼。

實(shí)例:

person = Person.new("Andrew")
person.password=("super password")
p person

#<Person:0x00007fb413154810 @name="Andrew", @password="super password">

解釋:在幕后,Ruby 在運(yùn)行代碼時(shí)將person.password ="something"行轉(zhuǎn)換為person.password =("something"),這僅調(diào)用方法password=,在右側(cè)傳遞的值作為參數(shù),這只是另一種方法。

同樣我們也有一種簡(jiǎn)寫(xiě)方法給屬性設(shè)置器:

class Person
  attr_writer :password
  def initialize(name)
    @name = name
  end

  def name
    @name
  end

end

2.8 對(duì)象作用域

您可以通過(guò)對(duì)象上的任何方法訪(fǎng)問(wèn):

  • 所有局部變量;

  • 所有實(shí)例變量;

  • 所有對(duì)象的方法。

讓我們寫(xiě)一個(gè)greet方法來(lái)為您展示。

實(shí)例:

class Person
  
  def name
    @name
  end

  def greet(other)
    name = other.name
    puts "Hi " + name + "! My name is " + @name + "."
  end
  
end

boy = Person.new("Andrew")
girl = Person.new("Alice")

boy.greet(girl)

#---- 輸出結(jié)果 ----
Hi Alice! My name is Andrew.

解釋:這是一個(gè)對(duì)象交互的例子,我們定義了一個(gè)greet方法,這個(gè)里面調(diào)用了@name實(shí)例變量,other是一個(gè)參數(shù),代表Person的對(duì)象。

注意事項(xiàng):當(dāng) Ruby 找到一個(gè)標(biāo)識(shí)符時(shí),Ruby 首先尋找一個(gè)局部變量,然后尋找一個(gè)方法。上述代碼name沒(méi)有調(diào)用實(shí)例方法name而是取的other.name的值就是因?yàn)檫@個(gè)原因。

2.9 self

每個(gè)對(duì)象都通過(guò)調(diào)用 self 的方式以每種方法認(rèn)識(shí)自己。這是 Ruby 中的一個(gè)特殊關(guān)鍵字,它的意思是對(duì)象本身。

class Person
  def initialize(name)
    @name = name
    p self
  end
end

person = Person.new("Anja")
p person

#---- 輸出結(jié)果 ----
#<Person:0x007f9994972428 @name="Anja">
#<Person:0x007f9994972428 @name="Anja">

解釋:如您所見(jiàn),我們兩次輸出相同的對(duì)象。一次在初始化方法中使用p self,一次在外部范圍中使用p person。您還可以看到,這兩個(gè)實(shí)例的神秘對(duì)象 ID 相同。因此我們可以知道它確實(shí)是同一對(duì)象。

所以,之前的方法我們可以這樣修改:

class Person
  def name
    @name
  end

  def greet(other)
    name = other.name
    puts "Hi " + name + "! My name is " + self.name + "."
  end
end

boy = Person.new("Andrew")
girl = Person.new("Alice")

boy.greet(girl)

#---- 輸出結(jié)果 ----
Hi Alice! My name is Andrew.

解釋:現(xiàn)在,我們?cè)俅卧趦蓚€(gè)不同的對(duì)象上調(diào)用方法name。當(dāng) Ruby 看到self時(shí),它知道我們正在引用當(dāng)前的Person對(duì)象,并在其上調(diào)用方法name。

注意事項(xiàng):self是一個(gè)關(guān)鍵字并不是一個(gè)方法,我們從下面的代碼可以證明。

person = Person.new("Andrew")
p person.self

#---- 輸出結(jié)果 ----
NoMethodError (undefined method `self' for #<Person:0x00007fb413290bc0 @name="Andrew">)

關(guān)鍵字是在 Ruby 中具有特殊含義的單詞,例如class,defendself。

2.10 類(lèi)方法(Class Method

類(lèi)方法的格式為:類(lèi)名.方法名(),通俗來(lái)說(shuō)就是類(lèi)名調(diào)用的方法,在其他語(yǔ)言中也稱(chēng)為靜態(tài)方法(Static Method)。

現(xiàn)在我們要輸出Person類(lèi)英語(yǔ)和中文名稱(chēng),對(duì)Person類(lèi)要這樣修改。

實(shí)例:

class Person
  def self.cn_name
    '人'
  end
  
  def self.en_name
    'Person'
  end
end

puts Person.cn_name
puts Person.en_name

#---- 輸出結(jié)果 ----Person

解釋?zhuān)?/strong> 上述我們定義了兩個(gè)類(lèi)方法,一個(gè)為cn_name,一個(gè)為en_name,我們使用Person.cn_namePerson.en_name來(lái)調(diào)用這兩個(gè)方法。

除此之外,我們還可以使用另外一種寫(xiě)法:

class Person
  class << self
    def cn_name
      '人'
    end

    def en_name
      'Person'
    end
  end
end

puts Person.cn_name
puts Person.en_name

解釋:這種寫(xiě)法在單件類(lèi)章節(jié)中會(huì)詳細(xì)講解,可以將它看成在一個(gè)類(lèi)中定義多個(gè)類(lèi)方法的一種便捷辦法。

假如我們要在類(lèi)的外面定義類(lèi)方法還可以這樣寫(xiě):

class Person
end

def Person.cn_name
  '人'
end

def Person.en_name
  'Person'
end

puts Person.cn_name
puts Person.en_name

#---- 輸出結(jié)果 ----Person

Tips:創(chuàng)建了一個(gè)類(lèi)的時(shí)候,類(lèi)方法和類(lèi)的作用域內(nèi)(非實(shí)例方法部分),self表示的是類(lèi)本身。

實(shí)例:

class Person
  puts "in class: #{self}"
  puts self == Person
  def self.cn_name
    puts "in class method: #{self}"
    puts self == Person
  end
end

#---- 輸出結(jié)果 ----
in class: Person
true
in class method: Person
true

3. 小結(jié)

本章中我們學(xué)習(xí)了如何創(chuàng)建一個(gè) Ruby 的類(lèi),如何定義一個(gè)類(lèi)、創(chuàng)建一個(gè)實(shí)例、定義實(shí)例方法、初始化對(duì)象、使用實(shí)例變量記錄、初始化屬性、屬性讀取器、屬性設(shè)置器、對(duì)象作用域以及了解了 self 的含義。