Module và include
Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 27 trên 57.
module là một nhóm có tên gồm các phương thức. Nó không thể tạo đối tượng, nhưng một lớp có thể include module đó, rồi mọi instance đều có các phương thức của module như thể lớp đã định nghĩa chúng. Đây gọi là mixin:
module Greetable
def greet
"Hello, I am #{name}"
end
end
class Person
include Greetable
attr_reader :name
def initialize(name)
@name = name
end
end
puts Person.new("Ada").greetĐầu ra:
Hello, I am AdaCác phương thức của module có thể gọi những phương thức mà lớp cung cấp, chẳng hạn như name ở trên. Vì vậy, một module có thể dùng cho nhiều lớp rất khác nhau, miễn là mỗi lớp cung cấp những gì module sử dụng:
module Greetable
def greet
"Hello, I am #{name}"
end
end
class Robot
include Greetable
def name
"R2"
end
end
class City
include Greetable
def name
"Paris"
end
end
puts Robot.new.greet
puts City.new.greetĐầu ra:
Hello, I am R2
Hello, I am ParisMột lớp chỉ có một lớp cha, nhưng có thể bao gồm bất kỳ số lượng module nào. include? kiểm tra xem một lớp có bao gồm một module hay không. Module đó xuất hiện trong ancestors, ngay sau lớp, đây là nơi Ruby tìm các phương thức của lớp:
module Swimmer
def swim
"swimming"
end
end
module Flyer
def fly
"flying"
end
end
class Duck
include Swimmer
include Flyer
end
d = Duck.new
puts "#{d.swim}, #{d.fly}"
puts Duck.include?(Flyer)
p Duck.ancestors.take(3)Đầu ra:
swimming, flying
true
[Duck, Flyer, Swimmer]Module cũng nhóm các lớp và hằng số liên quan dưới một tên gọi, gọi là namespace, để các tên không bị trùng lặp. Shop::Item và Game::Item là hai lớp khác nhau:
module Shop
TAX = 0.2
class Item
def label
"shop item, tax #{TAX}"
end
end
end
puts Shop::Item.new.label
puts Shop::TAXĐầu ra:
shop item, tax 0.2
0.2Thử thách
DễHoàn thành các module và lớp. Greetable#greet trả về Hello, I am Ada, sử dụng name của đối tượng. Walkable#walk(steps) cộng số bước vào bộ đếm lưu trong @steps (lần đầu bắt đầu từ nil) và trả về Ada walked 30 steps, tổng số bước tích lũy. Person bao gồm cả hai module; Robot chỉ bao gồm Greetable và tên của nó là R- theo sau bởi một số sê-ri.
Code được cung cấp tạo một người và một robot từ dòng đầu tiên (Ada 7), sau đó chạy các lệnh greet p, greet r hoặc walk 10 (dành cho người đó), in ra từng kết quả, rồi cuối cùng robot walks: false.
Code của bạn đặt trong greetable.rb, walkable.rb, person.rb và robot.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
require_relative 'greetable'
require_relative 'walkable'
require_relative 'person'
require_relative 'robot'
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
input << line.chomp
end
name, serial = input[0].split
person = Person.new(name)
robot = Robot.new(serial)
input.drop(1).each do |line|
command, arg = line.split
if command == "walk"
puts person.walk(arg.to_i)
else
target = arg == "p" ? person : robot
puts target.greet
end
end
puts "robot walks: #{Robot.include?(Walkable)}"
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpBiến instancePhương thức và selfto_s và inspectÔn tập: thẻ thư viện4Tính đóng gói
Phương thức riêng tưPhương thức được bảo vệPhương thức thiết lập riêng tưBảo vệ trạng tháiÔn tập: máy bán hàng tự động7Tính đa hình và duck typing
Tính đa hìnhDuck typingPhương thức trừu tượngcase và lớpÔn tập: phương thức thanh toán2Phương thức truy cập và self
Phương thức đọc và ghiPhương thức gán tùy chỉnhself trong phương thứcĐịnh danh và tính bằng nhauÔn tập: Danh sách liên hệ3Phương thức và biến của lớp
Phương thức lớpBiến thực thể của lớpHằng sốPhương thức tạo đối tượngÔn tập: mã giảm giá6Module và mixin
Module và includeMở rộng đối tượngModule ComparableModule EnumerableÔn tập: giải đấu thể thaoTự luyện tập: Trình biên dịch Ruby online