Lớp trong Ruby (Bài trước)

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


Đăng ký nhận bài viết mới
Lớp trong Ruby (Bài trước)