Bạn nên sử dụng một giao diện (không phải kế thừa) hoặc một loại cơ chế thuộc tính nào đó (thậm chí có thể là một cái gì đó hoạt động như khung mô tả tài nguyên).
Vì vậy
interface Colored {
Color getColor();
}
class ColoredBook extends Book implements Colored {
...
}
hoặc là
class PropertiesHolder {
<T> extends Property<?>> Optional<T> getProperty( Class<T> propertyClass ) { ... }
<V, T extends Property<V>> Optional<V> getPropertyValue( Class<T> propertyClass ) { ... }
}
interface Property<T> {
String getName();
T getValue();
}
class ColorProperty implements Property<Color> {
public Color getValue() { ... }
public String getName() { return "color"; }
}
class Book extends PropertiesHolder {
}
Làm rõ (chỉnh sửa):
Chỉ cần thêm các trường tùy chọn trong lớp thực thể
Đặc biệt với các tùy chọn-wrapper (chỉnh sửa: xem 4castle câu trả lời 's) Tôi nghĩ rằng đây (thêm các lĩnh vực trong thực thể ban đầu) là một cách hữu hiệu để thêm các thuộc tính mới trong một quy mô nhỏ. Vấn đề lớn nhất với phương pháp này là nó có thể hoạt động chống lại khớp nối thấp.
Hãy tưởng tượng lớp sách của bạn được xác định trong một dự án dành riêng cho mô hình miền của bạn. Bây giờ bạn thêm một dự án khác sử dụng mô hình miền để thực hiện một nhiệm vụ đặc biệt. Nhiệm vụ này đòi hỏi một tài sản bổ sung trong lớp sách. Hoặc là bạn kết thúc với sự kế thừa (xem bên dưới) hoặc bạn phải thay đổi mô hình miền phổ biến để thực hiện nhiệm vụ mới. Trong trường hợp sau, bạn có thể kết thúc với một loạt các dự án mà tất cả phụ thuộc vào thuộc tính của riêng chúng được thêm vào lớp sách trong khi lớp sách theo cách phụ thuộc vào các dự án này, vì bạn không thể hiểu lớp sách mà không có dự án bổ sung.
Tại sao thừa kế có vấn đề khi nói đến một cách để cung cấp các thuộc tính bổ sung?
Khi tôi thấy lớp mẫu của bạn "Sách", tôi nghĩ về một đối tượng miền thường có nhiều trường và kiểu con tùy chọn. Chỉ cần tưởng tượng bạn muốn thêm một tài sản cho những cuốn sách bao gồm một đĩa CD. Hiện nay có bốn loại sách: sách, sách có màu, sách có CD, sách có màu và CD. Bạn không thể mô tả tình huống này với sự kế thừa trong Java.
Với giao diện bạn tránh được vấn đề này. Bạn có thể dễ dàng soạn các thuộc tính của một lớp sách cụ thể với các giao diện. Đoàn và thành phần sẽ giúp bạn dễ dàng có được chính xác lớp bạn muốn. Với sự kế thừa, bạn thường kết thúc với một số thuộc tính tùy chọn trong lớp chỉ có ở đó vì một lớp anh chị em cần chúng.
Đọc thêm tại sao thừa kế thường là một ý tưởng có vấn đề:
Tại sao sự thừa kế thường được xem là một điều xấu bởi những người đề xướng OOP
JavaWorld: Tại sao kéo dài là xấu xa
Vấn đề với việc thực hiện một bộ giao diện để soạn một tập các thuộc tính
Khi bạn sử dụng các giao diện để mở rộng, mọi thứ đều ổn miễn là bạn chỉ có một bộ nhỏ. Đặc biệt là khi mô hình đối tượng của bạn được sử dụng và mở rộng bởi các nhà phát triển khác, ví dụ như trong công ty của bạn, số lượng giao diện sẽ tăng lên. Và cuối cùng, bạn kết thúc việc tạo ra một "giao diện thuộc tính" chính thức mới, bổ sung một phương thức mà các đồng nghiệp của bạn đã sử dụng trong dự án của họ cho khách hàng X cho một trường hợp sử dụng hoàn toàn không liên quan - Ugh.
chỉnh sửa: Một khía cạnh quan trọng khác được đề cập bởi gnasher729 . Bạn thường muốn tự động thêm các thuộc tính tùy chọn vào một đối tượng hiện có. Với sự kế thừa hoặc giao diện, bạn sẽ phải tạo lại toàn bộ đối tượng với một lớp khác không phải là tùy chọn.
Khi bạn mong đợi các tiện ích mở rộng cho mô hình đối tượng của mình đến một mức độ như vậy, bạn sẽ tốt hơn bằng cách mô hình hóa rõ ràng khả năng của tiện ích mở rộng động . Tôi đề xuất một cái gì đó giống như ở trên nơi mỗi "phần mở rộng" (trong trường hợp này là thuộc tính) có lớp riêng. Lớp này hoạt động như không gian tên và định danh cho phần mở rộng. Khi bạn đặt các quy ước đặt tên gói theo cách này cho phép số lượng tiện ích mở rộng vô hạn mà không gây ô nhiễm không gian tên cho các phương thức trong lớp thực thể ban đầu.
Trong phát triển trò chơi, bạn thường gặp phải tình huống bạn muốn soạn thảo hành vi và dữ liệu theo nhiều biến thể. Đây là lý do tại sao mô hình kiến trúc -thành phần-hệ thống kiến trúc trở nên khá phổ biến trong giới phát triển trò chơi. Đây cũng là một cách tiếp cận thú vị mà bạn có thể muốn xem xét, khi bạn mong đợi nhiều phần mở rộng cho mô hình đối tượng của mình.