Câu trả lời:
Một mixin thường được sử dụng với đa kế thừa. Vì vậy, theo nghĩa đó, không có sự khác biệt.
Chi tiết là một mixin hiếm khi hữu ích như một đối tượng độc lập.
Ví dụ: giả sử bạn có một mixin có tên "ColorAndDimension", bổ sung thuộc tính màu và chiều rộng và chiều cao.
Bây giờ, bạn có thể thêm ColorAndDimension vào lớp Shape, lớp Sprite, lớp Xe, v.v. Và tất cả chúng sẽ có cùng giao diện (ví dụ: get / setColor, get / setHeight / Width, v.v.)
Vì vậy, trong trường hợp chung, một sự kế thừa mixin IS. Nhưng bạn có thể tranh luận rằng đó là vấn đề về vai trò của lớp trong miền tổng thể như liệu một mixin có phải là một lớp "chính" hay đơn giản là một mixin.
Chỉnh sửa - chỉ để làm rõ.
Có, một mixin có thể được coi là, trong biệt ngữ hiện đại ngày nay, là một Giao diện với một Triển khai liên quan. Nó thực sự là đơn giản, cũ, đa kế thừa hàng ngày sử dụng một lớp đơn giản, cũ, hàng ngày. Nó chỉ là một ứng dụng cụ thể của MI. Hầu hết các ngôn ngữ không cung cấp trạng thái đặc biệt cho mixin; nó chỉ là một lớp được thiết kế để "trộn lẫn vào", thay vì được sử dụng độc lập.
Sự khác biệt giữa mixin và kế thừa là gì?
Kết hợp là một lớp cơ sở mà bạn có thể kế thừa để cung cấp chức năng bổ sung. Ví dụ về mã giả:
class Mixin:
def complex_method(self):
return complex_functionality(self)
Tên "trộn lẫn" cho biết nó được dùng để trộn với mã khác. Do đó, suy luận là bạn sẽ không tự khởi tạo lớp kết hợp. Đối tượng sau không có dữ liệu và không có ý nghĩa gì khi khởi tạo nó để gọi complex_method. (Bạn cũng có thể chỉ định nghĩa một hàm thay vì một lớp trong trường hợp đó.)
>>> obj = Mixin()
Thường thì hỗn hợp được sử dụng với các lớp cơ bản khác.
Do đó, mixin là một tập hợp con, hoặc trường hợp đặc biệt, của sự kế thừa.
Ưu điểm của việc sử dụng kết hợp trên kế thừa đơn là bạn có thể viết mã cho chức năng một lần và sau đó sử dụng cùng một chức năng trong nhiều lớp khác nhau. Điểm bất lợi là bạn có thể cần phải tìm kiếm chức năng đó ở những nơi khác chứ không phải nơi nó được sử dụng, vì vậy tốt hơn là bạn nên giảm thiểu nhược điểm đó bằng cách giữ nó gần đó.
Cá nhân tôi đã tìm thấy một sự kết hợp cần thiết để sử dụng thay vì kế thừa đơn lẻ trong đó chúng tôi đang lấy ra rất nhiều mã tương tự, nhưng các trường hợp thử nghiệm được khởi tạo dựa trên sự kế thừa của một trường hợp cơ sở và cách duy nhất để giữ mã gần hand (và trong cùng một mô-đun), không gây rối với các số phủ, là kế thừa từ đối tượng và để các trường hợp con kế thừa từ cả cơ sở trường hợp thử nghiệm phổ quát và cơ sở tùy chỉnh chỉ áp dụng cho chúng.
Cả hai đều là một dạng của lớp cha không nhằm mục đích khởi tạo.
Một mixin cung cấp chức năng, nhưng không thể trực tiếp sử dụng nó. Người dùng được dự định sử dụng nó thông qua một lớp (con).
Một lớp cơ sở trừu tượng cung cấp một giao diện, nhưng không có chức năng sử dụng được. Người dùng nhằm tạo ra chức năng được gọi bởi giao diện.
class Abstraction(metaclass=abc.ABCMeta):
@abc.abstractmethod
def complex_method(self):
return complex_functionality(self)
Tại đây, bạn bị ngăn không cho khởi tạo đối tượng này vì nó yêu cầu một lớp con để triển khai chức năng với một phương thức cụ thể (mặc dù bạn có thể truy cập chức năng bên trong từ super()
):
>>> obj = Abstraction()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Abstraction with
abstract methods complex_method
Trong Python, một số lớp trong abc
mô-đun là ví dụ về các lớp cha cung cấp chức năng thông qua kế thừa và các giao diện trừu tượng phải được thực thi bởi lớp con. Những ý tưởng này không loại trừ lẫn nhau.
Nói một cách đơn giản, mix-in chỉ là một lớp cơ sở mà bạn không thể tự khởi tạo nó và thường được sử dụng như một lớp cơ sở thứ cấp trong đa kế thừa.
mix-in là một trường hợp cụ thể, bị hạn chế của (nhiều) kế thừa được sử dụng cho các mục đích thực hiện; một số ngôn ngữ (ví dụ: Ruby) hỗ trợ nó mà không hỗ trợ đa kế thừa tổng quát.
Mixin là một khái niệm trừu tượng và bất cứ thứ gì đáp ứng được yêu cầu của nó đều có thể được coi là mixin.
Đây là một định nghĩa từ Wikipedia.
Trong ngôn ngữ lập trình hướng đối tượng, mixin là một lớp chứa các phương thức để các lớp khác sử dụng mà không cần phải là lớp cha của các lớp khác đó. Cách các lớp khác đó có quyền truy cập vào các phương thức của mixin phụ thuộc vào ngôn ngữ. Mixin đôi khi được mô tả là được "bao gồm" hơn là "kế thừa".
Tóm lại, sự khác biệt chính so với kế thừa là mix-in KHÔNG cần phải có mối quan hệ "is-a" như trong kế thừa.
Từ quan điểm triển khai, bạn có thể nghĩ nó như một giao diện với các triển khai. Ví dụ, một lớp trừu tượng trong Java có thể được coi là một mixin nếu Java hỗ trợ đa kế thừa.
"Mixin là một phần của một lớp theo nghĩa là nó được thiết kế để tạo ra các lớp hoặc mixin khác." -DDJ
Mixin là một lớp hoặc đoạn mã không nhằm mục đích sử dụng độc lập, nhưng thay vào đó bạn phải sử dụng nó bên trong một lớp khác. Có thể soạn nó như một trường / biến thành viên hoặc dưới dạng một đoạn mã. Tôi tiếp xúc nhiều nhất về sau. Nó tốt hơn một chút so với việc sao chép-dán mã bảng soạn sẵn.
Đây là một bài báo DDJ tuyệt vời giới thiệu chủ đề này.
SDK Half-Life 2 / "Nguồn" là một ví dụ tuyệt vời về hỗn hợp C ++. Trong môi trường đó, macro xác định các khối mã lớn có thể được thêm vào để tạo cho lớp một "hương vị" hoặc tính năng cụ thể.
Xem ví dụ về nguồn wiki: Tác giả một thực thể lôgic . Trong mã ví dụ, macro DECLARE_CLASS có thể được coi là một mixin. SDK nguồn sử dụng rộng rãi các kết hợp để chuẩn hóa mã truy cập dữ liệu và mô tả các hành vi cho các thực thể.
Với đa kế thừa, lớp mới có thể được tạo từ nhiều lớp cha. Bạn chỉ có thể gọi các phương thức được định nghĩa trong bất kỳ lớp cha nào.
Mặt khác, mixin là một lớp con trừu tượng có thể được sử dụng để chuyên biệt hóa hoạt động của nhiều lớp cha khác nhau. Mixin có thể gọi một phương thức (ví dụ sayHello(): String
) mặc dù chúng không định nghĩa một phương thức như vậy.
mixin M {
name: String
defmethod greetings() { print sayHello() + " " + name}
}
Như bạn thấy, bạn có thể gọi sayHello()
mặc dù nó không được định nghĩa ở bất kỳ đâu. Nếu bạn thêm mixin M
vào lớp C
, thì C
sẽ cung cấp sayHello()
phương thức.
Tôi nghĩ điều quan trọng cần lưu ý, rằng mixin không ngụ ý kế thừa . Theo wikipedia, Mixin là:
Trong ngôn ngữ lập trình hướng đối tượng, mixin là một lớp chứa các phương thức để các lớp khác sử dụng mà không cần phải là lớp cha của các lớp khác đó. Cách các lớp khác đó có quyền truy cập vào các phương thức của mixin phụ thuộc vào ngôn ngữ. Mixin đôi khi được mô tả là được "bao gồm" hơn là "kế thừa".
Cụ thể, bằng một ngôn ngữ như perl, có thể thêm mixin bằng cách sử dụng mô-đun Trình xuất:
package Mixins;
use Exporter qw(import);
our @EXPORT_OK = qw(pity);
# assumes it will be mixed-in to a class with a _who_do_i_pity method
sub pity {
my ($self) = @_;
printf("I pity %s\n", $self->_who_do_i_pity('da foo'));
}
Có thể trộn lẫn vào bất kỳ mô-đun nào có chứa một hoặc nhiều (các) phương thức tại một thời điểm:
package MrT
use Mixins qw(pity);
sub new {
return bless({}, shift);
}
sub _who_do_i_pity {
return 'da foo!'
}
Sau đó, trong MrT
mô-đun của bạn có thể được sử dụng như vậy:
use MrT;
MrT->new()->pity();
Tôi biết đó là một ví dụ vô lý, nhưng, nó đi đúng điểm ...