2012-11-07 34 views
8

Tôi có một câu hỏi thiết kế. Dưới đây là dấu thời gian InterfaceThiết kế tốt trong Generics

/** 
* <T> Type of Timestamp. For ex: Date, long, Calendar etc 
* 
*/ 
public interface TimeStamp<T> extends Comparable<TimeStamp<T>> 
{ 

    /** 
    * Returns the timestamp. 
    * @return 
    */ 
    public T getTimeStamp(); 

} 

tôi về cơ bản muốn có một lớp List rằng chỉ có thể chứa timestamps. Việc thêm bất kỳ thứ gì vào danh sách về cơ bản sẽ phụ thuộc vào dấu thời gian. Làm thế nào để khai báo lớp List của tôi.

Nếu tôi quyết định cho các thành phần, mã sẽ trông giống như:

public class TimeList<T> implements List<TimeStamp<T>> 
{  
    private List<TimeStamp<?>> list = new ArrayList<TimeStamp<?>>(); 
    //other list methods who will return based on list above 
    ..... 
} 

Nhưng ở trên không có ý nghĩa. Ví dụ nếu tôi có một lớp DefaultTimeStamp implments TimeStamp<Long> và nhanh chóng TimeList như

TimeList<DefaultTimeStamp> l = new TimeList<DefaultTimeStamp>(); 

Sau đó Anycall để l.add(elem) sẽ mong đợi một TimeStamp<DefaultTimeStamp> đó là sai.

Một tuyên bố: public class TimeList<TimeStamp<T>> implements List<TimeStamp<T>> sẽ cung cấp thời gian biên dịch lỗi

gì nên việc kê khai của TimeList<Type> của tôi? Cuối cùng nó chỉ là một danh sách chỉ chứa timestamps

+0

Bởi vì thêm bất cứ điều gì vào danh sách sẽ phụ thuộc vào dấu thời gian của mình . – Jatin

+1

bạn có muốn TimeList chứa TimeStamp cho T cụ thể cho bất kỳ T nào không? –

+0

Có. Điều đó là cần thiết để tính toán – Jatin

Trả lời

2

Tôi không hiểu lý do tại sao bạn muốn làm

TimeList<DefaultTimeStamp> l = new TimeList<DefaultTimeStamp>(); 

Nếu bạn muốn để có thể thêm bất kỳ loại TimeStamp<Long>. Cách trên sẽ buộc người dùng sử dụng DefaultTimeStamp nếu bạn có một số lý do thực hiện cụ thể để làm như vậy ... nhưng thường thì không, một cách chê bai.

TimeList<TimeStamp<Long>> l = new TimeList<TimeStamp<Long>>(); 
DefaultTimeStamp dts = new DefaultTimeStamp(System.currentTimeMillis()); 
l.add(dts); 

Chỉ hoạt động tốt!

+0

Đó chính xác là tôi không muốn. i mean- TimeList l = new TimeList (); – Jatin

+1

Tôi biết bạn không muốn làm điều đó, làm điều đáy :) – durron597

0

Không cần phải làm cho lớp TimeList chung chung. Bạn đơn giản có thể khai báo TimeList như:

public class TimeList implements List<Timestamp> { 

private List<Timestamp> list = new ArrayList<Timestamp>(); 

và sau đó sử dụng nó

TimeList l = new TimeList(); 

    l.add(new DefaultTimestamp1()); 
    l.add(new DefaultTimestamp2()); 

Nó hoạt động một cách hoàn hảo. Bạn chỉ có thể thêm các đối tượng mở rộng giao diện Timestamp.

+0

Đây là giải pháp khác.+1 – durron597

+1

Nhưng điều này sẽ đưa ra một số cảnh báo thời gian biên dịch. – Jatin

+0

Tôi không có cảnh báo, bạn có thể hiển thị các cảnh báo bạn nhận được và nói bạn đang sử dụng jdk nào không? – remigio

0
public class TimeList<T> extends ArrayList<TimeStamp<T>>{ 
} 

Vậy đó.

+0

Nếu các phương thức danh sách của anh ta chỉ trả về dựa trên biến 'private' của anh ta, thì đây là một cách tốt. Tuy nhiên, bằng cách thực hiện giao diện 'List', anh ta ẩn các phương thức tồn tại trong' ArrayList' và không nằm trong giao diện 'List'. (Chẳng hạn như 'EnsureCapacity'). –

0

Mặc dù tương tự có thể được lặp đi lặp lại trong Java, trong scala ai có thể làm điều đó bằng cách:

trait TimeStamp[T <: Comparable[T]] extends Comparable[TimeStamp[T]] 
{ 
def getTimeStamp:T; 
def compareTo(to:TimeStamp[T]) =this.getTimeStamp.compareTo(to.getTimeStamp) 
} 

Và TimeList khai thực hiện như sau:

class TimeList[T <: TimeStamp[_]] extends ArrayList[T] 
+0

Ai nói gì về Scala? –

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