Computer >> Máy Tính >  >> Lập trình >> Ruby

Tìm hiểu sâu về mô hình đối tượng Ruby

Theo Wikipedia, lập trình hướng đối tượng (OOP) là một mô hình lập trình dựa trên khái niệm "đối tượng", có thể chứa dữ liệu và mã:dữ liệu ở dạng trường (thường được gọi là thuộc tính hoặc thuộc tính) và mã ở dạng của các thủ tục (thường được gọi là các phương thức).

Ruby là một ngôn ngữ hướng đối tượng thuần túy, có nghĩa là trong ngôn ngữ Ruby, mọi thứ đều là một đối tượng. Những đối tượng này, bất kể chúng là chuỗi, số, lớp, mô-đun, v.v., hoạt động trong một hệ thống có tên là Mô hình đối tượng .

Ruby cung cấp một phương thức được gọi là object_id , có sẵn cho tất cả các đối tượng. Mã định danh này trả về một số nguyên và không bao giờ giống nhau đối với bất kỳ hai đối tượng nào. Hãy vào irb để làm bẩn tay; bạn có thể thực hiện việc này bằng cách nhập irb trong thiết bị đầu cuối của bạn.

Tìm hiểu sâu về mô hình đối tượng Ruby

Như đã thấy ở trên, chuỗi, số nguyên, mảng, lớp và thậm chí cả phương thức đều là đối tượng, vì chúng có ID đối tượng.

Trong bài viết này, chúng tôi sẽ trình bày chi tiết các khái niệm sau:

  • Các lớp và phiên bản
  • Kế thừa
  • Phương thức công khai, riêng tư và được bảo vệ
  • Mixin
  • Mô-đun
  • Phân cấp đối tượng

Lớp và Phiên bản

Trong Ruby, các lớp là nơi các thuộc tính và thái độ (hành động) của một đối tượng được định nghĩa. Nếu một đối tượng là hình tròn (một thuộc tính) và có thể nói (một hành động), chúng ta có thể biết từ lớp mà nó thuộc về vì các thuộc tính và hành động này được định nghĩa như một thứ gọi là phương thức trong lớp đó. Một đối tượng thuộc một lớp được gọi là thể hiện của lớp đó và được tạo (khởi tạo) bằng .new . Hãy bắt đầu bằng cách tạo một lớp có tên là Human . Tôi cho rằng chúng ta đều là con người, vì vậy điều này sẽ rất vui.

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

Khởi tạo phương thức xác định các yêu cầu cho một phiên bản mới của một lớp sẽ được tạo. Trong trường hợp trên, chúng ta có thể thấy rằng để tạo ra một con người mới, một cái tên là bắt buộc. Do đó, một phiên bản mới của con người có thể được tạo bằng lệnh Human.new(name) , trong đó tên là bất cứ điều gì bạn chọn. Trong trường hợp của chúng tôi, hãy sử dụng 'Henry'. Để kiểm tra điều này trong môi trường irb của chúng tôi, tất cả những gì chúng tôi cần làm là tải tệp bằng lệnh load './path_to_filename' và sử dụng lại lệnh để thực hiện lại tệp bất cứ khi nào thay đổi được thực hiện. Trong trường hợp của tôi, đó là load './Human.rb' bởi vì irb được mở trong thư mục chứa tệp đã nói. Để chạy mã mà không có irb, chúng ta cần thêm puts trước mỗi lệnh để hiển thị kết quả.

Tìm hiểu sâu về mô hình đối tượng Ruby

Khi chúng tôi cố gắng tạo một con người mới mà không có tên, chúng tôi gặp lỗi đối số vì tên là bắt buộc. Tuy nhiên, khi chúng tôi làm đúng, chúng tôi thấy rằng con người tên là Henry được tạo ra và thuộc về lớp Human . Henry do đó là một ví dụ của lớp Human .

@name biến được gọi là biến phiên bản vì @ nó bắt đầu bằng ký hiệu, có nghĩa là biến này có thể được tham chiếu bởi bất kỳ phương thức nào khác trong lớp, miễn là trường hợp lớp được đề cập tồn tại. Ở đây, chúng tôi đã tạo nó và đặt nó bằng tên mà đối tượng đã được khởi tạo.

Hãy tiến hành xác định các đặc điểm và hành động của bất kỳ đối tượng nào thuộc lớp này. Vì các đối tượng được tạo được gọi là thể hiện của lớp, nên các phương thức xác định hành vi của chúng được gọi là phương thức thể hiện . Con người có một cái tên và một số bộ phận cơ thể nhất định và có thể thực hiện một số hành động nhất định, vì vậy hãy xác định chúng.

def name
  @name
end

def no_of_legs
  2
end

def no_of_hands
  2
end

def speak
  'blablabla'
end

Chúng tôi đã thêm các phương thức lấy tên của con người được tạo ra, xác định số lượng chân và tay của con người cũng như cung cấp cho con người khả năng nói. Chúng ta có thể gọi các phương thức này trên cá thể lớp bằng cách sử dụng instance.method_name , như được hiển thị bên dưới.

Tìm hiểu sâu về mô hình đối tượng Ruby

Điều gì sẽ xảy ra nếu chúng tôi thay đổi ý định và quyết định rằng chúng tôi muốn thay đổi tên của cá thể lớp của chúng tôi là Henry. Ruby có một phương thức tích hợp mà chúng ta có thể thực hiện việc này, nhưng nó cũng có thể được thực hiện theo cách thủ công. Theo cách thủ công, chúng ta có thể thay đổi phương thức tên của mình từ chỉ là một phương thức getter lấy tên thành một phương thức setter cũng đặt nó thành một giá trị nếu một phương thức được cung cấp.

def name=(new_name)
  @name = new_name
end

Sử dụng attr_accessor tích hợp sẵn của Ruby , chúng ta có thể hủy phương thức tên của mình và thay thế nó bằng dòng attr_accessor :name :

class Human
  attr_accessor :name

  def initialize(name)
    @name = name
  end
# rest of the code
end

Bất kể phương pháp đã chọn là gì, vào cuối ngày, đây là những gì có thể đạt được.

Tìm hiểu sâu về mô hình đối tượng Ruby

Tất cả các phương thức được tạo cho đến nay được gọi là instance methods bởi vì chúng có thể được gọi trên bất kỳ thể hiện nào của lớp nhưng không được gọi trên chính lớp đó. Ngoài ra còn có một cái gì đó được gọi là class method , có thể được gọi trên chính lớp chứ không phải trên các cá thể của nó. Các phương thức lớp được đặt tên bằng cách đặt tiền tố tên phương thức bằng self. . Đây là một ví dụ:

# within the Human class
def self.introduction
  "I am a human, not an alien!"
end

Tìm hiểu sâu về mô hình đối tượng Ruby

Như chúng ta có thể thấy ở trên, phương thức lớp chỉ có sẵn cho chính lớp chứ không phải các thể hiện của nó. Ngoài ra, giống như các biến cá thể tồn tại, chúng ta có các biến lớp, được bắt đầu bằng hai @ các ký hiệu. Ví dụ được hiển thị bên dưới.

class Human
  attr_accessor :name
  @@no_cars_bought = 0 #class variable

  def initialize(name)
    @name = name
  end

  def self.no_cars_bought
    @@no_cars_bought
  end

  def buy_car
    @@no_of_cars_bought += 1
    "#{@name} just purchased a car"
  end
end

Trong ví dụ này, chúng tôi đã thêm buy_car phương pháp cho phép mọi người mua một chiếc xe hơi. Chúng tôi cũng đã tạo một biến lớp có tên là @@no_of_cars_bought điều đó tăng lên 1 mỗi khi một chiếc ô tô được mua. Cuối cùng, chúng tôi đã tạo một phương thức lớp có tên là no_cars_bought lấy số lượng ô tô đã được mua. Hãy xem cách này hoạt động như thế nào:

Tìm hiểu sâu về mô hình đối tượng Ruby

Tất cả các phương thức được xác định cho đến nay được gọi là công khai vì chúng có thể truy cập được bên ngoài lớp. Chúng tôi cũng có thể xác định các phương thức được gọi là private phương thức này chỉ có thể được truy cập trong một lớp. Hãy thử một ví dụ.

# at the bottom of the Human class
  def say_account_number
    "My account number is #{account_number}"
  end

  private

  def account_number
    "1234567890"
  end

Điều này dẫn đến kết quả sau:

Tìm hiểu sâu về mô hình đối tượng Ruby

Khi chúng tôi gọi henry.account_number , chúng tôi nhận được "NoMethodError" vì account_number là một phương thức riêng tư chỉ có thể được truy cập từ bên trong lớp. Khi được truy cập qua say_account_number như chúng ta đã làm, không có lỗi, vì phương thức này tồn tại trong cùng một lớp với phương thức private. Điều quan trọng cần lưu ý là mọi phương thức phiên bản sau private từ khóa trở thành một phương thức riêng; do đó, các phương thức private nên được định nghĩa ở cuối lớp sau tất cả các phương thức public.

Bạn đã bao giờ nghe nói về được bảo vệ các phương pháp? Vâng, đúng! Chúng cũng tồn tại, nhưng chúng ta sẽ nói về chúng sau khi chúng ta hiểu khái niệm về kế thừa .

Kế thừa

Bây giờ chúng ta đã biết về các lớp và cá thể, hãy tiến hành nói về kế thừa . Để hiểu đúng về khái niệm kế thừa, hãy tạo một lớp mới có tên là Mammal vì con người là động vật có vú. Tôi nhớ lại một câu nói nào đó trong lớp khoa học:"Tất cả con người là động vật có vú, nhưng không phải tất cả động vật có vú đều là người". Tôi cũng nhớ lại rằng một số đặc điểm của động vật có vú bao gồm sự hiện diện của lông hoặc lông và một bộ não phức tạp. Hãy đưa thông tin này vào Mammal lớp học.

class Mammal
  def has_hair?
    "Most certainly, Yes"
  end

  def has_complex_brain?
    "Well, as a mammal, what do you expect?"
  end
end

Bạn có nhớ cụm từ lớp học khoa học của tôi không? Nếu vậy, điều quan trọng là chúng ta phải tạo một mối quan hệ xác thực tuyên bố này. Vậy ta phải làm sao? Chúng tôi cho phép lớp người kế thừa các thuộc tính của Mammal lớp bằng cách thêm < Mammal theo định nghĩa lớp của nó.

class Human < Mammal
  # all other code
end

Một lớp kế thừa các thuộc tính của lớp khác được gọi là lớp con và lớp mà nó kế thừa được gọi là lớp cha . Trong trường hợp của chúng tôi, Human là lớp con và Mammal là lớp cha. Điều quan trọng cần lưu ý tại thời điểm này là nếu bạn đang xác định tất cả các lớp trong một tệp như chúng tôi đang làm ngay bây giờ, thì Mammal định nghĩa lớp phải đứng trước Human trong tệp của bạn, vì chúng tôi không muốn tham chiếu đến một biến trước khi nó được định nghĩa. Hãy xem con người hiện có những tính năng bổ sung nào.

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, con người hiện có quyền truy cập vào tất cả các thuộc tính được xác định trong Mammal lớp. Nếu chúng tôi xóa phần thừa kế (tức là chúng tôi xóa < Mammal từ dòng mã đó) và chạy lệnh henry.class.superclass , chúng tôi lấy "Đối tượng" làm phản hồi của mình. Điều này cho chúng ta biết rằng mọi lớp khi không kế thừa trực tiếp từ một lớp khác đều có lớp cha của nó là "Đối tượng", điều này càng củng cố thêm thực tế rằng trong Ruby, ngay cả các lớp cũng là đối tượng.

Tìm hiểu sâu về mô hình đối tượng Ruby

Bây giờ chúng ta đã biết về superclass là gì, đây là thời điểm hoàn hảo để nói về từ khóa super . Ruby cung cấp từ khóa này để cho phép sử dụng lại và sửa đổi các phương thức đã tồn tại trên một lớp cha. Trong Mammal của chúng tôi superclass, hãy nhớ lại rằng chúng ta có một phương thức được gọi là has_hair?; Điều gì sẽ xảy ra nếu chúng ta muốn thêm một số thông tin bổ sung dành riêng cho con người bất cứ khi nào phương thức đó được gọi? Đây là lúc mà việc sử dụng từ khóa super xuất hiện. Trong Human của chúng tôi lớp, chúng tôi xác định một phương thức có cùng tên, has_hair? .

def has_hair?
  super + ", but humans can be bald at times"
end

Khi từ khóa super được gọi, Ruby sẽ tìm kiếm tên phương thức đó trong lớp cha và trả về kết quả của nó. Trong phương pháp trên, chúng tôi đã thêm một số thông tin bổ sung vào kết quả được tạo ra bởi lớp cha 'has_hair? phương pháp.

Tìm hiểu sâu về mô hình đối tượng Ruby

Ruby chỉ hỗ trợ kế thừa một lớp, có nghĩa là bạn chỉ có thể kế thừa các thuộc tính của lớp từ một lớp. Tôi chắc rằng bạn đang tự hỏi điều gì sẽ xảy ra nếu bạn muốn thêm nhiều thuộc tính không dành riêng cho một lớp cụ thể vào lớp của mình. Ruby cũng cung cấp một điều khoản cho điều này dưới dạng mixin , nhưng trước khi nói về chúng, hãy nói về các phương pháp được bảo vệ .

Phương pháp được bảo vệ

Các phương thức được bảo vệ hoạt động giống như các phương thức riêng ở chỗ chúng có sẵn để được gọi trong một lớp và các lớp con của nó. Hãy tạo một phương thức được bảo vệ trong Mammal lớp học.

  #at the bottom of the Mammal class
  def body_status
    body
  end

  protected
  def body
    "This body is protected"
  end

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, chúng tôi không thể truy cập vào body vì nó được bảo vệ. Tuy nhiên, chúng tôi có thể truy cập nó từ body_status , là một phương thức khác bên trong Mammal lớp. Chúng ta cũng có thể truy cập các phương thức được bảo vệ từ các lớp con của lớp mà nó được định nghĩa. Hãy thử điều này trong Human lớp học.

# within the Human class
def check_body_status
  "Just a human checking that " + body.downcase
end

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, bất kể phương thức body có được xác định trong Human hay không lớp và được bảo vệ, Human lớp có thể truy cập vì nó là lớp con của Mammal lớp. Cũng có thể truy cập lớp con này với các phương thức riêng tư; tuy nhiên, điều này dẫn đến câu hỏi về sự khác biệt giữa các phương pháp này.

Các phương thức được bảo vệ có thể được gọi bằng cách sử dụng bộ thu rõ ràng, như trong receiver.protected_method , miễn là người nhận được đề cập là từ khóa self hoặc cùng lớp với self . Tuy nhiên, các phương thức riêng tư chỉ có thể được gọi bằng cách sử dụng bộ thu rõ ràng khi bộ thu rõ ràng là self .Hãy chỉnh sửa mã của chúng tôi bằng cách thay thế body.downcase với self.body.downcase trong check_body_status và thay đổi lệnh gọi phương thức riêng tư của chúng tôi để bao gồm cả self .

def check_body_status
  "Just a human checking that " + self.body.downcase
  # body method is protected
end

def say_account_number
  "My account number is #{self.account_number}"
  # account_number method is private
end

Tìm hiểu sâu về mô hình đối tượng Ruby

P.S:Trước Ruby 2.7 , khi gọi một phương thức riêng tư để lấy một số thông tin, hãy sử dụng self là không thể.

Hãy tiếp tục và thay thế từ self với một đối tượng trong cùng lớp với self . Trong trường hợp của chúng tôi, selfHenry , người đang gọi các phương thức và Henry là một bản sao của Human lớp kế thừa từ Mammal lớp học.

def check_body_status
  non_self = Human.new('NotSelf') #same class as self
  puts "Just #{non_self.name} checking that " + non_self.body.downcase
  # Mammal.new is also in the same class as self
  "Just a human checking that " + Mammal.new.body.downcase
end

def say_account_number
  non_self = Human.new('NotSelf')
  "My account number is #{non_self.account_number}"
end

Tìm hiểu sâu về mô hình đối tượng Ruby

Như hình trên, có thể thay thế self trong các phương thức được bảo vệ với một đối tượng cùng lớp với self , nhưng điều này là không thể với các phương pháp riêng tư.

Mixin

Mixin là một bộ mã được xác định trong một mô-đun , khi được đưa vào hoặc mở rộng cho bất kỳ lớp nào, sẽ cung cấp các khả năng bổ sung cho lớp đó. Một số mô-đun có thể được thêm vào một lớp, vì không có giới hạn nào cho điều này, không giống như những gì có được trong kế thừa lớp. Theo thông tin này, hãy tạo một mô-đun có tên là Movement để thêm khả năng di chuyển cho lớp người.

module Movement
  def hop
    "I can hop"
  end

  def swim
    "Ermmmm, I most likely can if I choose"
  end
end

Bước tiếp theo là đưa mô-đun này vào Human của chúng tôi lớp. Điều này được thực hiện bằng cách thêm cụm từ include <module_name> cho lớp được đề cập. Trong trường hợp của chúng tôi, điều này sẽ đòi hỏi phải thêm include Movement cho lớp người, như được hiển thị bên dưới.

class Human < Mammal
  include Movement
  # rest of the code
end

Hãy kiểm tra mã này:

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, các phương thức được trộn vào lớp thông qua mô-đun chỉ có sẵn cho các thể hiện của lớp chứ không phải chính lớp đó. Điều gì sẽ xảy ra nếu chúng ta muốn cung cấp các phương thức trong mô-đun cho lớp chứ không phải cá thể? Để thực hiện việc này, chúng tôi thay thế thuật ngữ "bao gồm" bằng "mở rộng", như trong extend Movement .

Tìm hiểu sâu về mô hình đối tượng Ruby

.extend Thuật ngữ cũng có thể được sử dụng trên các cá thể lớp nhưng theo một cách rất khác. Hãy tạo một mô-đun khác có tên là Parent .

module Parent
  def has_kids?
    "most definitely"
  end
end

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, sử dụng .extend(Parent) trên biến cha tạo ra has_kids? phương pháp có sẵn cho nó. Điều này đặc biệt hữu ích khi chúng ta không muốn các phương thức của mô-đun bị trộn lẫn vào mọi cá thể lớp. Do đó, extend chỉ có thể được sử dụng trên phiên bản cụ thể mà chúng tôi quan tâm.

Mô-đun

Mô-đun là nơi cư trú cho các lớp, phương thức, hằng số và thậm chí cả các mô-đun khác. Ngoài việc được sử dụng làm mixin, như đã thấy trước đó, các mô-đun còn có những công dụng khác. Chúng là một cách tuyệt vời để tổ chức mã của bạn để ngăn các tên xung đột với nhau, vì chúng cung cấp một lợi ích được gọi là không gian tên Trong Ruby, mọi lớp đều là một mô-đun, nhưng không có mô-đun nào là một lớp, vì các mô-đun không thể được khởi tạo hoặc kế thừa từ đó. / P>

module Male
  AGE = "Above 0"

  class Adult
    def initialize
      puts "I am an adult male"
    end
  end

  def self.hungry
    puts "There's no such thing as male food, I just eat."
  end

  module Grown
    def self.age
      puts "18 and above"
    end
  end
end

Bạn có thể nhận thấy rằng các phương thức được định nghĩa và gọi trong các mô-đun ở trên có tiền tố là self. . Điều này là do các mô-đun không thể được khởi tạo và bất kỳ phương thức nào được xác định bên trong chúng mà không có self. tiền tố sẽ chỉ có sẵn dưới dạng mixin, như chúng ta đã thấy trước đó khi chúng ta thảo luận về mixins . Để gọi một phương thức trên chính một mô-đun, chúng ta phải xác định điều này trên tên phương thức thông qua việc sử dụng self.method_name . Nhớ lại rằng chúng tôi cũng đã sử dụng self từ khóa trong các phương thức của lớp; nguyên tắc tương tự cũng được áp dụng ở đây.

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, để tiếp cận các lớp, mô-đun hoặc hằng số được xác định trong một mô-đun, chúng tôi sử dụng module_name::target_name . Để hiểu đúng khái niệm không gian tên, chúng tôi sẽ tạo một mô-đun khác chứa một lớp có tên là Adult và sau đó chúng ta sẽ xem cả hai lớp được phân biệt như thế nào.

module Female
  class Adult
    def initialize
      puts "I am an adult female"
    end
  end
    def self.hungry
      puts "Maybe there's such a thing as female food, I'm not sure. I just need to eat"
    end
end

Tìm hiểu sâu về mô hình đối tượng Ruby

Như hình trên, chúng ta có hai lớp mang tên "Adult". Bằng cách gói chúng trong các mô-đun của riêng chúng, chúng tôi có thể sử dụng những tên này mà không có bất kỳ sự nhầm lẫn nào về lớp người lớn chính xác được gọi mỗi lần. Hơn nữa, mã của chúng tôi dễ đọc hơn và có tổ chức hơn, và chúng tôi thực hiện nguyên tắc thiết kế tách các mối quan tâm, vì chúng tôi tách các khối mã khác nhau thành một số loại dựa trên chức năng của chúng.

Phân cấp đối tượng

Thật tuyệt vời khi hiểu các lớp, cá thể, mô-đun và khái niệm kế thừa, nhưng kiến ​​thức trong lĩnh vực này vẫn chưa đầy đủ nếu không hiểu hệ thống phân cấp đối tượng trong Ruby. Điều này đề cập đến thứ tự mà một phương thức được tìm kiếm trong Ruby. Một số phương pháp tồn tại để giúp chúng tôi hiểu hệ thống phân cấp này; một trong số chúng là ancestors phương pháp. Phương thức này không có sẵn cho các cá thể của lớp nhưng có thể được gọi trên chính các lớp và tổ tiên của chúng. Ví dụ được hiển thị bên dưới.

Tìm hiểu sâu về mô hình đối tượng Ruby

Từ kết quả của Human.ancestors , chúng ta thấy rằng phương thức này trả về lớp được đề cập, các mô-đun được bao gồm trực tiếp của nó, lớp cha của nó và các mô-đun được bao gồm trực tiếp của lớp cha; vòng lặp này tiếp tục cho đến khi nó đến Basic Object , là gốc của tất cả các đối tượng.

Một phương pháp khả dụng khác để lấy thêm thông tin về một lớp là phương thức included_modules .

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, lớp con người có hai mô-đun được bao gồm trong đó:mô-đun mà chúng tôi đã trực tiếp đưa vào bằng cách sử dụng include Movement và được bao gồm trong lớp Đối tượng. Điều này có nghĩa là mỗi lớp kế thừa các thuộc tính của lớp từ các lớp tổ tiên của nó và mỗi mô-đun có trong chúng sẽ được bao gồm trong đó. hơn những người khác trong con đường này. Chúng tôi sẽ xác định các phương thức có cùng tên nhưng các chuỗi đầu ra khác nhau và đặt chúng trong Human lớp, Movement mô-đun và Mammal lớp học.

# in the mammal class
def find_path
  "Found me in the Mammal class path"
end

# in the Movement module
def find_path
  "Found me in the Movement module path"
end
# in the Human class
def find_path
  "Found me in the Human class path"
end

Bây giờ chúng ta hãy thực hiện bài tập này.

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, thứ tự mà tổ tiên được đặt ra khi chúng ta gọi .ancestors trên một lớp là đường dẫn được theo sau khi tìm kiếm một phương thức được gọi trên một thể hiện của lớp đó. Đối với Human cá thể lớp mà chúng ta đã tạo, Ruby tìm kiếm phương thức trong chính lớp đó đầu tiên; nếu không được tìm thấy, nó sẽ chuyển sang bất kỳ mô-đun nào được bao gồm trực tiếp; nếu không tìm thấy, nó sẽ tiếp tục đến lớp cha và chu kỳ tiếp tục cho đến khi nó đến BasicObject . Nếu phương thức vẫn không được tìm thấy ở đó, một "NoMethodError" sẽ được trả về. Bằng cách sử dụng .ancestors , chúng tôi có thể xác định đường dẫn tra cứu cho một đối tượng và nơi các phương thức của nó tạo ra từ bất kỳ thời điểm nào.

Ruby cũng cung cấp một phương thức được gọi là methods , nhờ đó chúng tôi có thể xác định tất cả các phương thức có sẵn cho bất kỳ đối tượng nào. Chúng tôi thậm chí có thể thực hiện các phép trừ để hiển thị cái nào đến từ cha mẹ của nó và cái nào đặc biệt với nó. Ví dụ được hiển thị bên dưới.

Tìm hiểu sâu về mô hình đối tượng Ruby

Như được hiển thị ở trên, biến Henry có rất nhiều phương pháp có sẵn cho nó. Tuy nhiên, khi chúng tôi trừ chúng khỏi những thứ có sẵn cho Đối tượng , chúng tôi thấy rằng chúng tôi chỉ còn lại những phương thức mà chúng tôi đã xác định cụ thể trong tệp của mình và mọi phương thức khác đều được kế thừa. Điều này giống nhau đối với mọi đối tượng, lớp của nó và bất kỳ tổ tiên nào của nó. Hãy thoải mái làm bẩn tay của bạn bằng cách thử một số kết hợp liên quan đến Human.methods , Mammal.methods , Module.methods , và mọi lớp hoặc mô-đun khác được xác định trước đó; bạn sẽ thấy rằng điều này giúp bạn hiểu rõ hơn về mô hình đối tượng Ruby.