Một số vấn đề về kế thừa trong ruby
Như chúng ta đã biết, ruby là một ngôn ngữ hướng đối tượng, mọi thứ trong ruby gần như đều là object. Hôm nay mình xin đi vào 1 vấn đề trong OOP của ruby, cũng là 1 vấn đề rất quan trọng trong hướng đối tượng, đó là kế thừa - cụ thể là đa kế thừa trong ruby. Trước khi đi vào vấn đề chính, mình ...
Như chúng ta đã biết, ruby là một ngôn ngữ hướng đối tượng, mọi thứ trong ruby gần như đều là object. Hôm nay mình xin đi vào 1 vấn đề trong OOP của ruby, cũng là 1 vấn đề rất quan trọng trong hướng đối tượng, đó là kế thừa - cụ thể là đa kế thừa trong ruby.
Trước khi đi vào vấn đề chính, mình xin nhắc lại một chút định nghĩa về kế thừa, kế thừa là:
- Phát triển lớp mới từ lớp đã có
- Lớp mới được tạo thành là lớp con, lớp được kế thừa là lớp cha
- Có tính tái sử dụng bằng cách kế thừa các thành phần dữ liệu và hành vi của lớp cha.
Dễ dàng liên tưởng thực tế, 1 cha có thể có nhiều con, và 1 con thì chỉ có duy nhất 1 cha. Và vì thế 1 lớp chỉ được kế thừa duy nhất từ 1 lớp khác - đơn kế thừa. Nhưng trong một số thiết kế riêng, cần phải sử đa kế thừa để giải quyết, cũng như làm cho mô hình được sáng hơn. Vậy làm thế nào để có thể sử dụng đa kế thừa? Ruby sinh ra 1 định nghĩa đó là module giúp ta giải quyết được vấn đề này.
Module A def methodA puts "This is method of module A" end end Module B def methodB puts "This is method of module B" end end Class C include A include B end c = C.new c.methodA #This is method of module A c.methodB #This is method of module B
Và cũng chính từ đây nảy sinh ra vấn đề mà chúng ta cần xem xét.
Vấn đề 1:
Giả sử A và B cùng có 1 phương thức tên là methodX. Vậy khi C include A,B và gọi methodX thì methodX sẽ được gọi từ module nào?
Và ruby xử lí bằng cách, sẽ lấy từ module được include gần nhất tính từ trên xuống dưới.
Module A def methodX puts "This is method of module A" end end Module B def methodX puts "This is method of module B" end end Class C include A include B end c = C.new c.methodX #This is method of module B
Vấn đề 2:
Nếu cả module A,B cùng include một module C - chưa phương thức methodC. Sau đó class D cùng include module A,B. Và khi D gọi methodC thì nó sẽ hiểu lấy từ A hay B??
module C def methodC puts "This is method of module C" end end module A include C end module B include C end class D include A include B end d = D.new d.methodC #This is method of module C"
Về mặt kết quả, thì không có vấn đề gì, nhưng khi nghĩ về mặt kế thừa, sẽ cảm thấy bất ổn.