Các mẫu vấn đề điển hình được hưởng lợi từ một mã được thiết kế để sử dụng nhiều kế thừa là gì?
Đây chỉ là một ví dụ nhưng tôi thấy vô giá để cải thiện sự an toàn và giảm thiểu những cám dỗ để áp dụng thay đổi xếp tầng trong cả người gọi hoặc lớp con.
Nơi tôi đã tìm thấy nhiều sự kế thừa vô cùng hữu ích ngay cả đối với các giao diện không trạng thái trừu tượng nhất là thành ngữ giao diện không ảo (NVI) trong C ++.
Chúng thậm chí không thực sự là các lớp cơ sở trừu tượng nhiều như giao diện chỉ cần thực hiện một chút để thực thi các khía cạnh phổ biến của hợp đồng, vì chúng không thực sự thu hẹp tính tổng quát của hợp đồng nhiều hơn là thực thi tốt hơn .
Ví dụ đơn giản (một số có thể kiểm tra xem một tệp xử lý được truyền vào đang mở hay đại loại như thế):
// Non-virtual interface (public methods are nonvirtual/final).
// Since these are modeling the concept of "interface", not ABC,
// multiple will often be inherited ("implemented") by a subclass.
class SomeInterface
{
public:
// Pre: x should always be greater than or equal to zero.
void f(int x) /*final*/
{
// Make sure x is actually greater than or equal to zero
// to meet the necessary pre-conditions of this function.
assert(x >= 0);
// Call the overridden function in the subtype.
f_impl(x);
}
protected:
// Overridden by a boatload of subtypes which implement
// this non-virtual interface.
virtual void f_impl(int x) = 0;
};
Trong trường hợp này, có thể f
được gọi bởi một ngàn vị trí trong cơ sở mã, trong khif_impl
bị ghi đè bởi một trăm lớp con.
Sẽ rất khó để thực hiện loại kiểm tra an toàn này ở tất cả 1000 địa điểm gọi f
hoặc tất cả 100 địa điểm ghi đèf_impl
.
Bằng cách làm cho mục nhập này trở thành chức năng không ảo, nó cho tôi một vị trí trung tâm để thực hiện kiểm tra này. Và kiểm tra này không làm giảm sự trừu tượng trong một chút, vì nó chỉ đơn giản là khẳng định một điều kiện tiên quyết cần thiết để gọi hàm này. Theo một nghĩa nào đó, có thể củng cố hợp đồng được cung cấp bởi giao diện và giảm bớt gánh nặng kiểm tra x
đầu vào để đảm bảo nó tuân thủ các điều kiện tiên quyết hợp lệ ở tất cả 100 địa điểm ghi đè lên nó.
Đó là điều tôi ước mọi ngôn ngữ đều có, và cũng mong muốn, ngay cả trong C ++, đó là một khái niệm bản địa hơn một chút (ví dụ: không yêu cầu chúng tôi xác định một chức năng riêng để ghi đè).
Điều này cực kỳ hữu ích nếu bạn không làm điều này assert
trước và nhận ra rằng bạn cần nó sau này khi một số vị trí ngẫu nhiên trong cơ sở mã đang gặp phải các giá trị âm được chuyển đến f
.