Tính kế thừa các lớp Ruby
Có thể xây dựng một lớp con kế thừa các thuộc tính, phương thức từ lớp khác là lớp cha, lớp cơ sở.
Để khai báo một lớp kế thừa lớp khác dùng ký hiệu <
class Dog < Animal # Lớp Dog kế thừa Animal end
Tất nhiên tại lớp con có thể định nghĩa nó có các phương thức, biến riêng của nó, thậm chí
định nghĩa lại (overriding)
phương thức nào đó từ lớp cha
class Animal def initialize(name, color) @name = name @color = color end def speak puts "Hi" end end class Cat < Animal attr_accessor :age # thuộc tính riêng trong lớp kế thừa def speak # nạp chồng (overriding) phương thức puts "Meow" end end c = Cat.new("Lucy", "white") c.age = 2 c.speak # phương thức speak trong Cat chạy chứ không phải trong Animal chạy # outputs "Meow"
Trong cây kế thừa bạn có thể xây dựng các cấp tùy ý, tuy nhiên nhớ là Ruby không hỗ trọ đa kế thừa, một lớp không kế thừa trực tiếp nhiều lớp cha.
Gọi lại phương thức lớp cha khi nạp chồng
Ở ví dụ trên, ở lớp Cat định nghĩa lại (overriding) phương thức speak
,
trong trường hợp nếu muốn thi hành lại code của phương thức này ở lớp cơ sở và bổ sung thêm code
mới thì dùng đến từ khóa supper
class Animal def speak puts "Hi" end end class Cat < Animal def speak super # hàm speak của lớp cơ sở thược thi hành puts "Meow" # các code khá trong speak của lớp con end end c = Cat.new c.speak # Hi # kết quả chạy speak lớp cơ sở # Meow # kết quả các code khác của speak lớp con
Tương tự như vậy, supper
sử dụng phổ biến ở phương thức khởi tạo (giống Java).
class Animal def initialize(name) @name = name end end class Cat < Animal def initialize(name, age) super(name) # thi hành hàm khởi tạo của lớp cơ sở @age = age end def to_s "#{@name} is #{@age} years old." end end
Quá tải toán tử
Bạn có thể định nghĩa các toán tử (quá tải toán tử) để thực hiện phép toán trên các đối tượng được tạo ra.
Xem ví dụ sau:
class Shape attr_accessor :h, :w def initialize(h, w) self.h = h self.w = w end # Định nghĩa toán tử + để thi hành phép toán a + b, trả về đối tượng mới def +(other) Shape.new(self.h+other.h, self.w+other.w) end end a = Shape.new(7, 4) b = Shape.new(9, 18) c = a+b # thực hiện phép toán, tạo một đối tượng mới từ 2 đối tượng gốc puts c.h # outputs 16 puts c.w # outputs 22
Khả năng truy cập
Các thành viên trong lớp có thể được xác định nó có thể truy cập như thế nào từ các đối tượng khác,
từ lớp kế thừa ... Trong Ruby có ba mức điều khiển là public
, private
,
protected
public
Mặc định các phương thức khai báo mà không có chỉ định cụ thể nào thì khả năng truy
cập vào nó là public
, phương thức có thể truy cập từ lớp kế thừa, từ các đối tượng khác...
private
Đây là giới hạn riêng tư, phương thức chỉ được truy cập từ bên trong lớp. Để khai báo dùng từ
khóa private
class Person def initialize(age) @age = age end def show # có thể truy cập các phương thức private từ lớp (days_lived) puts "#{@age} years = #{days_lived} days" end private # từ khóa private def days_lived # days_lived là phương thức private @age * 365 end end p = Person.new(42) p.show p.days_lived # cố tính truy cập phương thức private từ bên ngoài sẽ lỗi
protected
Giới hạn là là không được truy cập từ bên ngoài, nhưng vẫn cho phép truy cập từ các lớp kế thừa