2012-08-10 30 views
6

Tôi có một lớp trừu tượng, mà tôi muốn tất cả các lớp con xác định một hằng số, dựa trên việc triển khai - nó chủ yếu là siêu dữ liệu về việc triển khai lớp.buộc các lớp con bao gồm hằng số trong lớp java trừu tượng

Trong lớp cha:

protected static final String OBJECT_NAME; 
protected static final String OBJECT_DEF; 

Và sau đó trong lớp con:

protected static final String OBJECT_NAME = "awesome class"; 
protected static final String OBJECT_DEF = "an awesome class that is also great"; 

Có cách nào để buộc triển khai của một lớp khai báo một hằng số?

+1

Có thể đáng lưu ý rằng hằng số có giá trị tiềm năng khác nhau không phải là hằng số! Vì vậy, đi với Peters câu trả lời. – TedTrippin

Trả lời

7

Bạn có thể bắt buộc lớp con xác định phương thức có thể là hằng số cho lớp đó.

protected abstract String objectName(); 
protected abstract String objectDef(); 

Lưu ý: nếu bạn có phân lớp phụ của các lớp con, chúng có thể "quên" để ghi đè các phương pháp này.

+0

sắp giới thiệu điều này;) –

+2

Điều tốt nhất bạn có thể nhận được. Vì O.P. không thể làm chính xác những gì anh ấy muốn làm, đây chắc chắn là cách tiếp cận tốt nhất. –

+0

Cảm ơn! Không nghĩ về điều này (rõ ràng). Không có cách nào để đảm bảo thực hiện tiểu phụ của lớp tĩnh thực hiện các phương pháp này là có? –

0

Không. Bạn không thể.

Bạn thậm chí không thể khai báo hằng số trong lớp cha trừu tượng mà không gán giá trị cụ thể cho chúng. Trong trường hợp khác, bạn sẽ gặp lỗi. Bạn nên khởi tạo các trường cuối cùng trong quá trình khai báo hoặc trong lớp khởi tạo.

Bạn có thể khai báo các phương thức trừu tượng sẽ khởi tạo biến của bạn (nhưng điều này sẽ bị làm xáo trộn hơn). Như thế này:

protected String OBJECT_NAME = getObjectNameValue(); 

public abstract String getObjectNameValue(); 

Nhưng trong trường hợp này, các biến và phương pháp của bạn không nên tĩnh. Bởi vì bạn không thể định nghĩa các phương thức tĩnh là trừu tượng (look here for explanation).

Hoặc bạn có thể sử dụng phương pháp trực tiếp thay vì các biến như Peter Lawrey đề xuất, điều này sẽ dễ đọc hơn.

0

Điều này sẽ không hoạt động theo cách đó. Tôi sẽ xác định các chức năng như trừu tượng:

protected abstract String objectName(); 
protected abstract String objectDef(); 

Và trong lớp con:

private static final String OBJECT_NAME = "awesome class"; 
private static final String OBJECT_DEF = "bla"; 

protected String objectName(){ 
    return OBJECT_NAME; 
} 

protected String objectDef(){ 
    return OBJECT_DEF; 
} 

Các phương pháp này không static, nhưng tôi nghĩ rằng đây là gần nhất bạn có thể nhận được những gì bạn muốn.

1

Cũng có thể đi cho một giao diện như bạn không có giá trị mặc định hợp lý cho các lớp cha:

Inreface HasObjectNameAndDef { 
    public String getObjectName(); 
    public String getObjectDef(); 
} 

và có các lớp học thực tế của bạn thực hiện giao diện. Bạn nhận được kiểm tra dễ dàng hơn là tiền thưởng.

-1

Tôi biết bạn đang nói gì.

Tôi ví dụ, muốn có một giao diện (mà tôi gọi ExecutableList) có một String lĩnh vực contant gọi USER_FRIENDLY_NAME

public interface ExecutableList<T extends ExecutableList<T,E>,E> //This is type parameter 
    extends List<E>,            //self referencing. Trust 
      Comparable<E>,          //me, it has its uses. 
{ 
    /** This would declare a constant but leave it to sub-interfaces/classes to define it. */ 
    abstract String USER_FRIENDLY_NAME; 

    //Define the rest of your interface 

} 

Thật không may, điều này là không thể trong Java. Khi bạn khai báo một trường trong giao diện Java, nó ngụ ý các biến tố public, staticfinal.Một thay đổi trong tương lai đối với ngôn ngữ lập trình Java MIGHT cho phép thêm abstract, do đó làm cho các sửa đổi ngụ ý public abstract static final String USER_FRIENDLY_NAME; nhưng trong khi bạn có thể xác định rõ ràng các quy tắc cho điều này, việc sử dụng từ abstract sẽ gây nhầm lẫn, như abstractfinal thường được hiểu là định nghĩa ý nghĩa ngược lại.

Tôi đang vượt qua các ngón tay của mình rằng phiên bản Java trong tương lai sẽ thực hiện việc này. Tôi đã nghe nói rằng các phương thức giao diện riêng sẽ được thêm vào trong Java 9 (để sử dụng giữa các phương thức mặc định) nhưng không có từ nào được bổ sung vào ngôn ngữ này. Có một số vấn đề tương thích ngược để xem xét trước, tôi chắc chắn. Nếu bất cứ ai từ Oracle đọc điều này, XIN VUI LÒNG CHO CHÚNG TÔI QUYẾT ĐỊNH VỀ CÁC GIAO TIẾP VÀ LET INHERITING CLASSES/INTERFACES DEFINE THEM !!!

Trong thời gian chờ đợi, tùy chọn duy nhất của bạn là xác định phương thức String getUserFriendlyName(); trong giao diện hoặc lớp trừu tượng của bạn. Không thanh lịch và có lẽ không hiệu quả, nhưng hiện tại bạn không có lựa chọn nào khác.

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