Bạn không thể kế thừa một enum từ một enum khác, mặc dù bạn có thể có enum của bạn thực hiện một giao diện. Các vấn đề kỹ thuật (mà tất cả enums ngầm mở rộng java.lang.Enum
, do đó họ không thể mở rộng lớp khác, chỉ thực hiện các giao diện bổ sung) là không phải ngẫu nhiên:
Đối với hầu hết các phần, khả năng mở rộng của enums hóa ra là một xấu ý kiến. Điều gây nhầm lẫn là các phần tử của loại tiện ích mở rộng là trường hợp của loại cơ sở và không ngược lại. Không có cách nào tốt để liệt kê tất cả các phần tử của loại cơ sở và phần mở rộng của nó. Cuối cùng, khả năng mở rộng sẽ làm phức tạp nhiều khía cạnh của thiết kế và triển khai.
Từ Effective Java 2nd Edition khoản 34.
Tuy nhiên, tôi không hoàn toàn hiểu được vấn đề của bạn: chưa bạn sử dụng values()
cho iterating qua enum của bạn? Sau đó, bạn không nên lo lắng về việc mở rộng enum của bạn với các giá trị mới.
Hãy chỉ định rõ ràng hơn những gì "hỏng" được cho là có ý nghĩa.
Cập nhật: vì vậy bạn cần phải có bộ riêng biệt của ban nhạc với nhiều loại khác nhau của các ngôi sao - điều này có thể được thực hiện bằng sự đếm riêng biệt mở rộng một giao diện chung, ví dụ:
interface Band {
String getName();
void doStuff();
...
}
enum BandsVI implements Band {
V, I;
public String getName() { return toString(); }
public void doStuff() { /* do stuff as appropriate for these bands */ }
...
}
enum BandsJHK implements Band {
J, H, K;
public String getName() { return toString(); }
public void doStuff() { /* do stuff as appropriate for these bands */ }
...
}
Và bạn có thể sử dụng các bằng làm cho lớp Ngôi sao chung chung của bạn:
class Star<T extends Enum<T> & Band> {
private Class<T> bandType;
public Star(Class<T> bandType) { this.bandType = bandType; }
public void printBandNames() {
for (Band b : bandType.getEnumConstants())
System.out.println(b.getName());
}
public void doStuffOnAllBands() {
for (Band b : bandType.getEnumConstants())
b.doStuff();
}
}
...
Star<BandsVI> star1 = new Star<BandsVI>(BandsVI.class);
Star<BandsJHK> star2 = new Star<BandsJHK>(BandsJHK.class);
star1.printBandNames(); // prints V I
star2.printBandNames(); // prints J H K
Điều này hoạt động tốt nếu các nhóm được tổ chức thành các nhóm riêng biệt. Nếu có những ngôi sao với các nhóm nhạc hỗn hợp, tuy nhiên, bạn có thể thích một cách tiếp cận khác:
class Star {
private List<? extends Band> bandTypes;
public Star(List<? extends Band> bandTypes) { this.bandTypes = bandTypes; }
public void printBandNames() {
for (Band b : bandTypes)
System.out.println(b.getName());
}
...
}
...
Star star1 = new Star(Arrays.asList(BandsVI.values()));
Star star3 = new Star(Arrays.asList(new Band[]{BandsVI.V, BandsVI.I, BandsJHK.K}));
...
này cho phép bạn thiết lập sao với một sự pha trộn độc đoán của ban nhạc. Tuy nhiên, theo cách này, bạn không thể sử dụng EnumSet
hoặc EnumMap
trên các băng tần.
Tại sao bạn lặp lại qua BandNames? – ILMTitan
Trong trường hợp một Ban nhạc mới cần phải được thêm vào, ở khắp mọi nơi mà tôi sử dụng một BandName sẽ không cần phải được cập nhật. – rhombidodecahedron
Các gói tương ứng với những gì? Đó là, tại sao bạn phân lớp các lớp này ở nơi đầu tiên? –