<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Ruby 中的面向對象編程 II > 原文: [https://zetcode.com/lang/rubytutorial/oop2/](https://zetcode.com/lang/rubytutorial/oop2/) 在 Ruby 教程的這一部分中,我們將繼續討論 Ruby 中的面向對象編程。 我們從屬性訪問器開始。 我們將介紹類常量,類方法和運算符重載。 我們將定義多態,并展示如何在 Ruby 中使用它。 我們還將提到模塊和異常。 ## Ruby 屬性訪問器 所有 Ruby 變量都是私有的。 只能通過方法訪問它們。 這些方法通常稱為設置器和獲取器。 創建一個設置器和一個獲取器方法是非常常見的任務。 因此,Ruby 具有方便的方法來創建兩種類型的方法。 它們是`attr_reader`,`attr_writer`和`attr_accessor`。 `attr_reader`創建獲取器方法。 `attr_writer`方法為該設置器創建設置器方法和實例變量。 `attr_accessor`方法同時創建獲取器方法,設置器方法及其實例變量。 ```ruby #!/usr/bin/ruby class Car attr_reader :name, :price attr_writer :name, :price def to_s "#{@name}: #{@price}" end end c1 = Car.new c2 = Car.new c1.name = "Porsche" c1.price = 23500 c2.name = "Volkswagen" c2.price = 9500 puts "The #{c1.name} costs #{c1.price}" p c1 p c2 ``` 我們有汽車類。 在類的定義中,我們使用`attr_reader`和`attr_writer`為`Car`類創建兩個獲取器和設置器方法。 ```ruby attr_reader :name, :price ``` 在這里,我們創建兩個名為`name`和`price`的實例方法。 注意,`attr_reader`將方法的符號作為參數。 ```ruby attr_writer :name, :price ``` `attr_writer`創建兩個名為`name`和`price`的設置方法,以及兩個實例變量`@name`和`@price`。 ```ruby c1.name = "Porsche" c1.price = 23500 ``` 在這種情況下,調用了兩個設置器方法以用一些數據填充實例變量。 ```ruby puts "The #{c1.name} costs #{c1.price}" ``` 在這里,調用了兩個獲取器方法以從`c1`對象的實例變量獲取數據。 ```ruby $ ./arw.rb The Porsche costs 23500 Porsche: 23500 Volkswagen: 9500 ``` 這是示例的輸出。 如前所述,`attr_accessor`方法創建獲取器,設置器方法及其實例變量。 ```ruby #!/usr/bin/ruby class Book attr_accessor :title, :pages end b1 = Book.new b1.title = "Hidden motives" b1.pages = 255 p "The book #{b1.title} has #{b1.pages} pages" ``` 我們有一個`Book`類,其中`attr_accessor`創建兩對方法和兩個實例變量。 ```ruby class Book attr_accessor :title, :pages end ``` 設置標題和頁面方法以及`@title`和`@pages`實例變量的`attr_accessor`方法。 ```ruby b1 = Book.new b1.title = "Hidden motives" b1.pages = 255 ``` 創建一個`Book`類的對象。 兩種設置方法填充對象的實例變量。 ```ruby p "The book #{b1.title} has #{b1.pages} pages" ``` 在此代碼行中,我們使用兩種獲取器方法來讀取實例變量的值。 ```ruby $ ./accessor.rb "The book Hidden motives has 255 pages" ``` 這是示例輸出。 ## Ruby 類常量 Ruby 使您可以創建類常量。 這些常量不屬于具體對象。 他們屬于階級。 按照約定,常量用大寫字母表示。 ```ruby #!/usr/bin/ruby class MMath PI = 3.141592 end puts MMath::PI ``` 我們有一個帶有`PI`常量的`MMath`類。 ```ruby PI = 3.141592 ``` 我們創建一個`PI`常量。 請記住,Ruby 中的常量不是強制性的。 ```ruby puts MMath::PI ``` 我們使用`::`運算符訪問`PI`常量。 ```ruby $ ./classconstant.rb 3.141592 ``` 運行示例,我們看到此輸出。 ## Ruby `to_s`方法 每個對象都有一個`to_s`方法。 它返回對象的字符串表示形式。 請注意,當`puts`方法將對象作為參數時,將調用該對象的`to_s`。 ```ruby #!/usr/bin/ruby class Being def to_s "This is Being class" end end b = Being.new puts b.to_s puts b ``` 我們有一個`Beinging`類,其中我們重寫了`to_s`方法的默認實現。 ```ruby def to_s "This is Being class" end ``` 創建的每個類都從基`Object`繼承。 `to_s`方法屬于此類。 我們覆蓋`to_s`方法并創建一個新的實現。 我們提供了一個易于理解的對象描述。 ```ruby b = Being.new puts b.to_s puts b ``` 我們創建一個`Beinging`類,并調用`to_s`方法兩次。 第一次是顯式的,第二次是隱式的。 ```ruby $ ./tostring.rb This is Being class This is Being class ``` 這是我們運行示例時得到的。 ## 運算符重載 運算符重載是指不同的運算符根據其參數具有不同的實現的情況。 在 Ruby 中,運算符和方法之間只有微小的區別。 ```ruby #!/usr/bin/ruby class Circle attr_accessor :radius def initialize r @radius = r end def +(other) Circle.new @radius + other.radius end def to_s "Circle with radius: #{@radius}" end end c1 = Circle.new 5 c2 = Circle.new 6 c3 = c1 + c2 p c3 ``` 在示例中,我們有一個`Circle`類。 我們在類中重載了`+`運算符。 我們使用它來添加兩個圓形對象。 ```ruby def +(other) Circle.new @radius + other.radius end ``` 我們定義一個帶有`+`名稱的方法。 該方法將兩個圓形對象的半徑相加。 ```ruby c1 = Circle.new 5 c2 = Circle.new 6 c3 = c1 + c2 ``` 我們創建兩個圓形對象。 在第三行中,我們添加這兩個對象以創建一個新對象。 ```ruby $ ./operatoroverloading.rb Circle with radius: 11 ``` 將這兩個圓形對象相加會創建第三個半徑為 11 的對象。 ## Ruby 類方法 Ruby 方法可以分為類方法和實例方法。 類方法在類上調用。 不能在類的實例上調用它們。 類方法不能訪問實例變量。 ```ruby #!/usr/bin/ruby class Circle def initialize x @r = x end def self.info "This is a Circle class" end def area @r * @r * 3.141592 end end p Circle.info c = Circle.new 3 p c.area ``` 上面的代碼示例展示了`Circle`類。 除了構造器方法外,它還具有一個類和一個實例方法。 ```ruby def self.info "This is a Circle class" end ``` 以`self`關鍵字開頭的方法是類方法。 ```ruby def area "Circle, radius: #{@r}" end ``` 實例方法不能以`self`關鍵字開頭。 ```ruby p Circle.info ``` 我們稱為類方法。 注意,我們在類名上調用該方法。 ```ruby c = Circle.new 3 p c.area ``` 要調用實例方法,我們必須首先創建一個對象。 實例方法總是在對象上調用。 在我們的例子中,`c`變量保存對象,然后在圓對象上調用`area`方法。 我們利用點運算符。 ```ruby $ ./classmethods.rb "This is a Circle class" 28.274328 ``` 描述 Ruby 中類方法的代碼示例的輸出。 有三種方法可以在 Ruby 中創建類方法。 ```ruby #!/usr/bin/ruby class Wood def self.info "This is a Wood class" end end class Brick class << self def info "This is a Brick class" end end end class Rock end def Rock.info "This is a Rock class" end p Wood.info p Brick.info p Rock.info ``` 該示例包含三個類。 它們每個都有一個類方法。 ```ruby def self.info "This is a Wood class" end ``` 類方法可以以`self`關鍵字開頭。 ```ruby class << self def info "This is a Brick class" end end ``` 另一種方法是將方法定義放在`class << self`構造之后。 ```ruby def Rock.info "This is a Rock class" end ``` 這是在 Ruby 中定義類方法的第三種方法。 ```ruby $ ./classmethods2.rb "This is a Wood class" "This is a Brick class" "This is a Rock class" ``` 我們看到在`Wood`,`Brick`和`Rock`類上調用所有三個類方法的輸出。 ## 在 Ruby 中創建實例方法的三種方法 Ruby 有三種創建實例方法的基本方法。 實例方法屬于對象的實例。 使用點運算符在對象上調用它們。 ```ruby #!/usr/bin/ruby class Wood def info "This is a wood object" end end wood = Wood.new p wood.info class Brick attr_accessor :info end brick = Brick.new brick.info = "This is a brick object" p brick.info class Rock end rock = Rock.new def rock.info "This is a rock object" end p rock.info ``` 在示例中,我們從`Wood`,`Brick`和`Rock`類創建三個實例對象。 每個對象都有一個定義的實例方法。 ```ruby class Wood def info "This is a wood object" end end wood = Wood.new p wood.info ``` 這可能是定義和調用實例方法的最常用方法。 `info`方法在`Wood`類中定義。 之后,創建對象,然后在對象實例上調用`info`方法。 ```ruby class Brick attr_accessor :info end brick = Brick.new brick.info = "This is a brick object" p brick.info ``` 另一種方法是使用屬性訪問器創建方法。 這是一種方便的方法,可以節省程序員的鍵入時間。 `attr_accessor`創建兩個方法,即獲取器和設置器方法。它還創建一個實例變量來存儲數據。 使用信息設置器方法,將創建磚對象,并將數據存儲在`@info`變量中。 最后,該消息由`info`獲取器方法讀取。 ```ruby class Rock end rock = Rock.new def rock.info "This is a rock object" end p rock.info ``` 在第三種方法中,我們創建一個空的`Rock`類。 該對象被實例化。 以后,將動態創建一個方法并將其放置到對象中。 ```ruby $ ./threeways.rb "This is a wood object" "This is a brick object" "This is a rock object" ``` 示例輸出。 ## Ruby 多態 多態是對不同的數據輸入以不同方式使用運算符或函數的過程。 實際上,多態意味著如果類 B 從類 A 繼承,則不必繼承關于類 A 的所有內容; 它可以完成 A 類所做的某些事情。 (維基百科) 通常,多態是以不同形式出現的能力。 從技術上講,它是重新定義派生類的方法的能力。 多態與將特定實現應用于接口或更通用的基類有關。 請注意,在靜態類型的語言(例如 C++ ,Java 或 C# )和動態類型的語言(例如 Python 或 Ruby)中,多態的定義有所不同。 在靜態類型的語言中,當編譯器在編譯時或運行時確定方法定義時,這一點很重要。 在動態類型的語言中,我們專注于具有相同名稱的方法執行不同操作的事實。 ```ruby #!/usr/bin/ruby class Animal def make_noise "Some noise" end def sleep puts "#{self.class.name} is sleeping." end end class Dog < Animal def make_noise 'Woof!' end end class Cat < Animal def make_noise 'Meow!' end end [Animal.new, Dog.new, Cat.new].each do |animal| puts animal.make_noise animal.sleep end ``` 我們有一個簡單的繼承層次結構。 有一個`Animal`基類和兩個后代,即`Cat`和`Dog`。 這三個類中的每一個都有其自己的`make_noise`方法實現。 后代方法的實現替換了`Animal`類中方法的定義。 ```ruby class Dog < Animal def make_noise 'Woof!' end end ``` `Dog`類中的`make_noise method`的實現替換了`Animal`類中的`make_noise`的實現。 ```ruby [Animal.new, Dog.new, Cat.new].each do |animal| puts animal.make_noise animal.sleep end ``` 我們為每個類創建一個實例。 我們在對象上調用`make_noise`和`sleep`方法。 ```ruby $ ./polymorhism.rb Some noise Animal is sleeping. Woof! Dog is sleeping. Meow! Cat is sleeping. ``` 這是`polymorhism.rb`腳本的輸出。 ## Ruby 模塊 Ruby `Module`是方法,類和常量的集合。 模塊與類相似,但有一些區別。 模塊不能有實例,也不能是子類。 模塊用于對相關的類進行分組,方法和常量可以放入單獨的模塊中。 這也防止了名稱沖突,因為模塊封裝了它們所包含的對象。 在這方面,Ruby 模塊類似于 C# 名稱空間和 Java 包。 模塊還支持在 Ruby 中使用 mixins。 mixin 是 Ruby 工具,用于創建多重繼承。 如果一個類從一個以上的類繼承功能,那么我們說的是多重繼承。 ```ruby #!/usr/bin/ruby puts Math::PI puts Math.sin 2 ``` Ruby 具有內置的`Math`模塊。 它具有多種方法和一個常數。 我們使用`::`運算符訪問`PI`常量。 和類中一樣,方法由點運算符訪問。 ```ruby #!/usr/bin/ruby include Math puts PI puts sin 2 ``` 如果我們在腳本中包含模塊,則可以直接引用`Math`對象,而無需使用`Math`名稱。 使用`include`關鍵字將模塊添加到腳本中。 ```ruby $ ./modules.rb 3.141592653589793 0.9092974268256817 ``` 程序的輸出。 在下面的示例中,我們展示了如何使用模塊來組織代碼。 ```ruby #!/usr/bin/ruby module Forest class Rock ; end class Tree ; end class Animal ; end end module Town class Pool ; end class Cinema ; end class Square ; end class Animal ; end end p Forest::Tree.new p Forest::Rock.new p Town::Cinema.new p Forest::Animal.new p Town::Animal.new ``` Ruby 代碼可以在語義上進行分組。 巖石和樹木屬于森林。 游泳池,電影院,廣場屬于一個城鎮。 通過使用模塊,我們的代碼具有一定的順序。 動物也可以在森林和城鎮中。 在一個腳本中,我們不能定義兩個動物類。 他們會發生沖突。 將它們放在不同的模塊中,我們可以解決問題。 ```ruby p Forest::Tree.new p Forest::Rock.new p Town::Cinema.new ``` 我們正在創建屬于森林和城鎮的對象。 要訪問模塊中的對象,我們使用::運算符。 ```ruby p Forest::Animal.new p Town::Animal.new ``` 將創建兩個不同的動物對象。 Ruby 解釋器可以在它們之間進行區分。 它通過模塊名稱來標識它們。 ```ruby $ ./modules3.rb #<Forest::Tree:0x97f35ec> #<Forest::Rock:0x97f35b0> #<Town::Cinema:0x97f3588> #<Forest::Animal:0x97f3560> #<Town::Animal:0x97f3538> ``` 這是`modules3.rb`程序的輸出。 本節的最終代碼示例將演示使用 Ruby 模塊的多重繼承。 在這種情況下,這些模塊稱為混合模塊。 ```ruby #!/usr/bin/ruby module Device def switch_on ; puts "on" end def switch_off ; puts "off" end end module Volume def volume_up ; puts "volume up" end def vodule_down ; puts "volume down" end end module Pluggable def plug_in ; puts "plug in" end def plug_out ; puts "plug out" end end class CellPhone include Device, Volume, Pluggable def ring puts "ringing" end end cph = CellPhone.new cph.switch_on cph.volume_up cph.ring ``` 我們有三個模塊和一個類。 模塊代表一些功能。 可以打開和關閉設備。 許多對象可以共享此功能,包括電視,移動電話,計算機或冰箱。 我們沒有為每個對象類創建這種被切換為開/關的功能,而是將其分離到一個模塊中,如有必要,該模塊可以包含在每個對象中。 這樣,代碼可以更好地組織和緊湊。 ```ruby module Volume def volume_up ; puts "volume up" end def vodule_down ; puts "volume down" end end ``` `Volume`模塊組織負責控制音量級別的方法。 如果設備需要這些方法,則僅將模塊包含在其類中。 ```ruby class CellPhone include Device, Volume, Pluggable def ring puts "ringing" end end ``` 手機使用`include`方法添加所有三個模塊。 模塊的方法在`CellPhone`類中混合。 并且可用于該類的實例。 `CellPhone`類還具有特定于它的自己的`ring`方法。 ```ruby cph = CellPhone.new cph.switch_on cph.volume_up cph.ring ``` 創建一個`CellPhone`對象,然后在該對象上調用三個方法。 ```ruby $ ./mixins.rb on volume up ringing ``` 運行示例將給出此輸出。 ## Ruby 異常 異常是表示偏離正常程序執行流程的對象。 引發,引發或引發異常。 在執行應用期間,許多事情可能出錯。 磁盤可能已滿,我們無法保存文件。 互聯網連接可能斷開,我們的應用嘗試連接到站點。 所有這些都可能導致我們的應用崩潰。 為了防止這種情況的發生,我們應該預期并應對預期程序操作中的錯誤。 為此,我們可以使用異常處理。 異常是對象。 它們是內置`Exception`類的后代。 異常對象攜帶有關異常的信息。 它的類型(異常的類名),可選的描述性字符串和可選的回溯信息。 程序可以是`Exception`的子類,或更常見的是`StandardError`的子類,以獲取提供有關操作異常的其他信息的自定義`Exception`對象。 ```ruby #!/usr/bin/ruby x = 35 y = 0 begin z = x / y puts z rescue => e puts e p e end ``` 在上面的程序中,我們有意將數字除以零。 這會導致錯誤。 ```ruby begin z = x / y puts z ``` 可能失敗的語句放置在`begin`關鍵字之后。 ```ruby rescue => e puts e p e end ``` 在`rescue`關鍵字后面的代碼中,我們處理了一個異常。 在這種情況下,我們將錯誤消息打印到控制臺。 `e`是發生錯誤時創建的異常對象。 ```ruby $ ./zerodivision.rb divided by 0 #<ZeroDivisionError: divided by 0> ``` 在示例的輸出中,我們看到了異常消息。 最后一行顯示名為`ZeroDivisionError`的異常對象。 程序員可以使用`raise`關鍵字自己引發異常。 ```ruby #!/usr/bin/ruby age = 17 begin if age < 18 raise "Person is a minor" end puts "Entry allowed" rescue => e puts e p e exit 1 end ``` 18 歲以下的年輕人不允許進入俱樂部。 我們在 Ruby 腳本中模擬這種情況。 ```ruby begin if age < 18 raise "Person is a minor" end puts "Entry allowed" ``` 如果此人是未成年人,則會引發異常情況。 如果`raise`關鍵字沒有特定的異常作為參數,則會引發`RuntimeError`異常,將其消息設置為給定的字符串。 該代碼未到達`puts "Entry allowed"`行。 代碼的執行被中斷,并在救援塊處繼續執行。 ```ruby rescue => e puts e p e exit 1 end ``` 在救援塊中,我們輸出錯誤消息和`RuntimeError`對象的字符串表示形式。 我們還調用`exit`方法來通知環境腳本執行錯誤結束。 ```ruby $ ./raise_exception.rb Person is a minor #<RuntimeError: Person is a minor> $ echo $? 1 ``` 未成年人未獲準進入俱樂部。 bash `$?`變量設置為腳本的退出錯誤。 Ruby 的`ensure`子句創建一個始終執行的代碼塊,無論是否存在異常。 ```ruby #!/usr/bin/ruby begin f = File.open("stones", "r") while line = f.gets do puts line end rescue => e puts e p e ensure f.close if f end ``` 在代碼示例中,我們嘗試打開并讀取`Stones`文件。 I/O 操作容易出錯。 我們很容易會有異常。 ```ruby ensure f.close if f end ``` 在確保塊中,我們關閉文件處理器。 我們檢查處理器是否存在,因為它可能尚未創建。 分配的資源通常放置在確保塊中。 如果需要,我們可以創建自己的自定義異常。 Ruby 中的自定義異常應繼承自`StandardError`類。 ```ruby #!/usr/bin/ruby class BigValueError < StandardError ; end LIMIT = 333 x = 3_432_453 begin if x > LIMIT raise BigValueError, "Exceeded the maximum value" end puts "Script continues" rescue => e puts e p e exit 1 end ``` 假設我們處于無法處理大量數字的情況。 ```ruby class BigValueError < StandardError ; end ``` 我們有一個`BigValueError`類。 該類派生自內置的`StandardError`類。 ```ruby LIMIT = 333 ``` 超出此常數的數字在我們的程序中被視為`big`。 ```ruby if x > LIMIT raise BigValueError, "Exceeded the maximum value" end ``` 如果該值大于限制,則拋出自定義異常。 我們給異常消息`"Exceeded the maximum value"`。 ```ruby $ ./custom_exception.rb Exceeded the maximum value #<BigValueError: Exceeded the maximum value> ``` 運行程序。 在本章中,我們結束了關于 Ruby 語言的面向對象編程的討論。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看