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

Giải thích về sự kế thừa của Ruby - Tìm hiểu OOP ngay hôm nay!

Kế thừa lớp là một tính năng cơ bản của OOP (Lập trình hướng đối tượng) giúp bạn tạo phiên bản cụ thể và chuyên biệt hơn của bất kỳ lớp nào.

Đây là một ví dụ :

Food -> Fruit -> Orange

Có một mối quan hệ giữa các lớp này!

Chúng ta có thể nói rằng quả cam là một loại trái cây, nhưng trái cây cũng là thức ăn.

Lớp cha (còn được gọi là siêu lớp hoặc lớp cơ sở ) luôn chung chung hơn các lớp con.

Fruit (chung chung hơn) là lớp cha của Orange (cụ thể hơn).

Trong Ruby, nó trông giống như thế này :

class Food
end

class Fruit < Food
end

class Orange < Fruit
end

Một trong những hàm ý của kế thừa trong Ruby là mọi phương thức &mọi hằng số được xác định trên Food sẽ có trên Fruit và cả trên Orange .

Các phương thức được truyền từ lớp cơ sở, nhưng không phải ngược lại.

Mục đích của Thừa kế là gì?

Bạn có thể nghĩ rằng việc tạo một cấu trúc phân cấp đối tượng cung cấp một số kiểu tổ chức “cảm thấy tốt” cho mã của bạn, nhưng còn nhiều thứ hơn thế nữa.

Kế thừa được sử dụng để tạo một phiên bản khác của lớp cha phù hợp cho một mục đích cụ thể. Có thể nó cần một số tính năng hoặc phương thức bổ sung không có ý nghĩa trong lớp cha.

Đây là một ví dụ :

Tất cả các loại trái cây đều có màu sắc, trọng lượng và tên gọi.

Một số loại trái cây có thể có các đặc điểm đặc biệt không giống với các loại trái cây khác, vì vậy bạn tạo một loại mới kế thừa các đặc điểm của TẤT CẢ các loại trái cây (màu sắc, trọng lượng, v.v.) và sau đó bạn thêm đặc tính đặc biệt.

Đó là ý tôi muốn nói đến sự chuyên môn hóa.

Một ví dụ khác :

Bạn có một lớp ghi vào cơ sở dữ liệu, nhưng bạn muốn một phiên bản khác của lớp (có thể cho mục đích gỡ lỗi) ghi lại tất cả các hoạt động của cơ sở dữ liệu.

Trong trường hợp này, bạn muốn có mẫu trang trí.

Bạn có thể đọc giải thích chi tiết về bài viết này, nhưng ý tưởng cơ bản là bạn sử dụng kế thừa để bao bọc một lớp khác và sau đó thêm một cái gì đó mới vào nó.

Mà không cần phải thay đổi bản gốc!

Thừa kế trong Thế giới Thực

Được rồi.

Chúng tôi đã tìm hiểu về kế thừa, nhưng bạn có biết rằng bạn đang sử dụng nó hàng ngày với tư cách là một nhà phát triển Ruby không?

Bản thân Ruby sử dụng kế thừa để bật các phương pháp như:

  • puts
  • class
  • super

Điều này là do tất cả các đối tượng Ruby đều kế thừa từ Object theo mặc định.

Vì vậy, nếu bạn tạo một lớp học như thế này :

class Apple
end

Lớp cha của nó là Object :

Apple.superclass
# Object

Đó là lý do tại sao bạn có thể sử dụng các phương pháp như những phương pháp được đề cập ở trên.

Ví dụ:khi bạn gọi puts Ruby tìm kiếm phương thức này trong lớp của bạn.

Sau đó :

  • Nó tìm kiếm phương thức trong một trong các lớp cha
  • Nếu không tìm thấy, nó sẽ bắt đầu lại từ đối tượng và nó sẽ cố gắng tìm method_missing
  • Nếu không được tìm thấy, nó sẽ tạo ra NoMethodError hoặc NameError nếu phương thức được gọi mà không có đối tượng rõ ràng (a.size so với size , trong đó a là đối tượng rõ ràng)

Bạn có thể tìm thêm các ví dụ về kế thừa trong Rails.

Ngay tại đây :

class ApplicationController < ActionController::Base
end

Bộ điều khiển :

class SessionsController < ApplicationController
end

Mô hình :

class Comment < ApplicationRecord
  belongs_to :article
end

Tính kế thừa có ở khắp mọi nơi trong Ruby, nhưng đôi khi nó không phải là giải pháp phù hợp.

Thành phần:Một sự thay thế cho sự kế thừa

Kế thừa có những hạn chế nhất định.

Ví dụ :

Bạn muốn xây dựng một máy tính từ các bộ phận.

Chúng tôi nói rằng máy tính có các bộ phận, nhưng các bộ phận riêng lẻ tự nó không phải là máy tính.

Nếu bạn tách chúng ra, chúng sẽ không thể thực hiện được chức năng của chúng.

Chúng tôi cần thứ khác…

Chúng tôi cần bố cục!

Thành phần xây dựng các lớp trong đó các phần khác nhau kết hợp với nhau để thực hiện một chức năng.

Cũng giống như một máy tính.

Dưới đây là một ví dụ về bố cục trong thực tế :

class Computer
  def initialize(memory, disk, cpu)
    @memory = memory
    @disk   = disk
    @cpu    = cpu
  end
end

Máy tính được cung cấp các bộ phận cần thiết để hoạt động.

Đây là thành phần.

Nguyên tắc thay thế Liskov

Tính kế thừa sẽ mạnh mẽ khi được sử dụng trong những tình huống phù hợp.

Nhưng giống như tất cả các công cụ, nó có thể bị lạm dụng!

Trên thực tế, có một câu trích dẫn phổ biến từ cuốn sách Mẫu thiết kế ban đầu giống như sau:

“Ưu tiên bố cục hơn là kế thừa.”
Mẫu thiết kế:Các yếu tố của phần mềm hướng đối tượng có thể tái sử dụng

Để đảm bảo rằng bạn đang sử dụng kế thừa đúng cách có một nguyên tắc bạn có thể tuân theo, L từ SOLID.

Nó là viết tắt của "Nguyên tắc thay thế Liskov".

Điều này nói rằng các lớp con của bạn phải có thể được sử dụng thay cho lớp cơ sở của bạn.

Nói cách khác :

Nếu bạn kế thừa từ Fruit &color là một chuỗi, bạn không muốn thay đổi color để trả về một biểu tượng trong một lớp con.

Ví dụ :

Người dùng Fruit phụ thuộc vào color trả về một chuỗi.

class Fruit
  def color
    "orange"
  end
end

Điều này phá vỡ LSP :

class Orange < Fruit
  def color
    :orange
  end
end

Nếu bạn thay đổi color để trả về một biểu tượng, thì bạn không thể thay thế một Fruit đối tượng có Orange .

Tại sao?

Bởi vì nếu bạn gọi một phương thức như split trên một biểu tượng, bạn sẽ gặp lỗi.

Đó là một phương pháp mà các ký hiệu không có.

Nhưng chuỗi thì có.

Một dấu hiệu đỏ khác là khi lớp con của bạn không phải là một chuyên môn thực sự của lớp cha và bạn chỉ đang sử dụng lớp cha để chia sẻ các phương thức tiện ích.

Tóm tắt

Bạn đã học về kế thừa và cấu tạo trong Ruby!

Bạn có thể sử dụng kế thừa để tạo phiên bản chuyên biệt của lớp mẹ và thành phần để tập hợp các thành phần lại với nhau thành một tổng thể. Hãy nhớ làm theo LSP nguyên tắc nếu bạn không muốn làm rối tung lên.

Bây giờ bạn có thể viết Mã hướng đối tượng tốt hơn 🙂

Cảm ơn vì đã đọc.