2010-04-15 40 views
18

Đây là những gì tôi đang tìm kiếm để thực hiện, tôi có một lớp học có một enum của một số giá trị và tôi muốn phân lớp đó và thêm nhiều giá trị cho enum. Đây là một ví dụ tồi, nhưng:Có thể mở rộng Java Enums không?

public class Digits 
{ 
public enum Digit 
{ 
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9 
} 
} 

public class HexDigits extends Digits 
{ 
public enum Digit 
{ 
    A, B, C, D, E, F 
} 
} 

để HexDigits.Digit chứa tất cả chữ số hex. Điều đó có thể không?

+1

Bạn đã thử chưa? – bmargulies

+1

Câu trả lời là 'không' (xem câu trả lời bên dưới để biết chi tiết). Sách của Josh Bloch * Hiệu quả Java * có giải thích và giải pháp tốt cho việc này. – David

+1

Tôi đã thử, đó là lý do tôi đăng ở đây! – CaseyB

Trả lời

31

Không thể thực hiện được. Điều tốt nhất bạn có thể làm là làm cho hai enums thực hiện và giao diện và sau đó sử dụng giao diện đó thay vì enum. Vì vậy:

interface Digit { 
    int getValue(); 
} 

enum Decimal implements Digit { 
    ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE; 

    private final int value; 

    Decimal() { 
    value = ordinal(); 
    } 

    @Override 
    public int getValue() { 
    return value; 
    } 
} 

enum Hex implements Digit { 
    A, B, C, D, E, F; 

    private final int value; 

    Hex() { 
    value = 10 + ordinal(); 
    } 

    @Override 
    public int getValue() { 
    return value; 
    } 
} 
+0

Điều này có biên dịch không? tôi nghĩ rằng nó sẽ không! – Narayan

+0

@Narayan có một lỗi trình biên dịch nhỏ (hiện đã được sửa) nhưng nếu không thì nó hoạt động. – cletus

+0

tốt rằng bạn đã sửa chữa nó, tôi upvoted bạn anyways :) – Narayan

5

số

Enums không thể được subclassed.

Lý do ở đây là một điều tra xác định một số giá trị cố định. Phân lớp sẽ phá vỡ điều này.

4

Không, bạn không thể. Nếu bạn nhìn vào định nghĩa của Enum, trường hợp của nó là cuối cùng và không thể được mở rộng. Điều này có ý nghĩa nếu bạn hiểu enums là hữu hạn, final bộ giá trị.

Có sự khác biệt giữa một số (một artifact cú pháp) mà có thể là nhị phân, thập phân, hex hoặc bất cứ điều gì, và thực tế ngữ nghĩa số, đơn vị số đại diện cú pháp bởi một chữ số trong một ngữ cảnh (hệ thống cơ sở .)

Trong ví dụ của bạn, những gì bạn cần là

  • enums xác định chữ số syntatic (chữ số thập phân và chữ cái những biểu tượng đại diện cho pháp hệ thập lục phân; có nghĩa là, thẻ enum, và
  • lớp xác định hành vi (hoặc ngữ pháp) cần thiết cho cú pháp đại diện cho một số như một số (sử dụng chữ số [cú pháp] enums).

Tức là, bạn có mã thông báo hoặc ký hiệu và ngữ pháp/hành vi cho biết liệu luồng mã thông báo có đại diện cho một số trong một cơ sở nhất định hay không.

Nhưng đó là một chút ngoài tang (và như bạn đã nói, nó chỉ là một ví dụ vì lợi ích của ví dụ). Quay lại để mở rộng enums ...

... bạn không thể và bạn không nên. Enums không có nghĩa là đại diện cho những thứ có thể được mở rộng. Chúng đại diện cho một số: hằng số bộ giá trị không đổi. Có những thứ không thể kế thừa được.

Ngoài ra, đừng rơi vào bẫy mở rộng vì lợi ích của tiện ích mở rộng hoặc để cố gắng buộc cấu trúc vào mã hoặc mô hình của bạn.

Điều này có vẻ hợp lý khi đặt một bộ giá trị thành phần mở rộng của một giá trị khác. Thường xuyên hơn không, nó không phải là.Sử dụng thừa kế để tái sử dụng hành vi hoặc cấu trúc phức tạp, không chỉ dữ liệu có ít hoặc không có cấu trúc với hành vi không thể tái sử dụng được liên kết với nó.

-5

đồng ý rằng enum không có nghĩa là được mở rộng ... nhưng khi phải đối mặt với Tapestry 5 chọn thành phần ... và phiên bản enum của nó là phiên bản tốt nhất .... so với đối tượng phức tạp (ridiculously?) mô hình ví dụ trên mạng ... có thể xem cách mở rộng và enum hấp dẫn cho trường hợp này ....

btw (seque gripe) những gì heck là nó với tấm thảm ném đi chứ không phải là xây dựng trên/tốt nhất thực hành khuôn khổ jsp ? tốt nhất điều này tạo ra một bộ phận phát triển ui, khiến công nghệ java yếu hơn cho trải nghiệm ...

+3

Câu hỏi ban đầu không có tham chiếu đến Tapestry, vì vậy thật khó để xem câu trả lời này sẽ hỗ trợ người hỏi như thế nào. –

0

Không thể thực hiện được. Và có một lý do. Hãy tưởng tượng bạn có thể mở rộng một enum:

enum A { ONE, TWO } 
enum B extends A { THREE } // for a total { ONE, TWO, THREE } 

Bây giờ bạn có thể làm điều này:

B b = B.THREE 
A a = b // a = B.THREE ? 

Nhưng B.THREE không phải là một lựa chọn hợp lệ cho A.

Tất nhiên bạn có thể làm cho chúng không đa hình, nhưng sau đó nó không thực sự mở rộng.

Các vấn đề liên quan