Thuật toán tuyến tính hóa C3 cho độ phân giải phương thức trong nhiều ngôn ngữ OO kế thừa: Tìm kiếm sự biện minh cho một số chi tiết triển khai


7

Theo này mô tả về trật tự giải quyết phương pháp của Python (MRO), hay còn gọi là C3 tuyến tính , thuật toán có thể được mô tả một cách đệ quy như sau:

L(O) = <O>
L(C) = <C> + merge(L(B1),..., L(Bn), <B1,...,Bn>)

Ở đâu

  • O là lớp mà mọi lớp đều kế thừa.
  • Clà một lớp kế thừa trực tiếp từ B1, ... Bn,, theo thứ tự này.
  • <>là các dấu phân cách danh sách.
  • + là toán tử ghép nối danh sách.
  • merge hợp nhất các đối số danh sách của nó thành một danh sách duy nhất, theo cách được mô tả dưới đây.

Phần trên có thể được viết lại bằng từ (trích dẫn từ tài liệu Python ở trên):

tuyến tính hóa của C là tổng của C cộng với sự hợp nhất của tuyến tính hóa của cha mẹ và danh sách của cha mẹ.

Các mergethuật toán được mô tả như sau (thực chất được trích dẫn từ tài liệu Python, nhưng hơi reworded):

Hãy xem xét phần đầu của danh sách đầu tiên, tức là L (B1) [0]: nếu đó là phần đầu tốt , tức là nếu nó không nằm trong phần đuôi thích hợp của bất kỳ danh sách nào khác, hãy thêm nó vào phần tuyến tính hóa của C và xóa nó từ tất cả các danh sách trong hợp nhất. Mặt khác, hãy xem xét phần đầu của danh sách tiếp theo, v.v. Lặp lại cho đến khi không còn lớp nào nữa, hoặc không có phần đầu tốt. Trong trường hợp sau, không thể xây dựng hợp nhất.

Ví dụ sau đây được đưa ra như một minh họa. Giả sử Akế thừa trực tiếp từ BC, theo thứ tự này, và giả sử rằng các tuyến tính hóa của BC

L(B) = <B, D, E, O>
L(C) = <C, D, F, O>

Sau đó A, tuyến tính hóa là

L(A) = <A> + merge(<B,D,E,O>, <C,D,F,O>, <B,C>)
     = <A, B> + merge(<D,E,O>, <C,D,F,O>, <C>)
     = <A, B, C> + merge(<D,E,O>, <D,F,O>)
     = <A, B, C, D> + merge(<E,O>, <F,O>)
     = <A, B, C, D, E> + merge(<O>, <F,O>)
     = <A, B, C, D, E, F> + merge(<O>, <O>)
     = <A, B, C, D, E, F, O>

Câu hỏi của tôi là: về mặt mô tả ban đầu của thuật toán, mục đích của nó là gì để đưa ra danh sách <B1,...,Bn>cha mẹ trực tiếp làm đối số merge? Thuật toán sẽ tạo ra kết quả khác nhau nếu đối số này bị bỏ qua?

Câu trả lời:


5

Không có danh sách cuối cùng:

merge(<B,D,O>, <C,F,O>, <D,O>) =
  <B,D,C,F,O> 

Với danh sách cuối cùng:

merge(<B,D,O>, <C,F,O>, <D,O>, <B,C,D>) =
  <B> + merge(<D,O>, <C,F,O>, <D,O>, <C,D>) =
  <B,C> + merge(<D,O>, <F,O>, <D,O>, <D>) =
  <B,C,D,F,O>

Không có danh sách cuối cùng:

merge(<B,D,C,O>, <C,F,O>, <D,O>) =
  <B,D,C,F,O> 

Với danh sách cuối cùng:

merge(<B,D,C,O>, <C,F,O>, <D,O>, <B,C,D>) =
  <B> + merge(<D,C,O>, <C,F,O>, <D,O>, <C,D>) =
  no-merge

Theo trực giác, danh sách cuối cùng buộc kết quả cuối cùng phải tương thích với thứ tự <B1,...,Bn>. Điều đó có thể thay đổi thứ tự hoặc làm cho sự hợp nhất thất bại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.