2011-11-30 24 views
22

Có thể tham số hóa chung một phương thức chấp nhận EITHER ClassA OR InterfaceB không?Generic OR thay vì AND <T mở rộng số | CharSequence>

Không biên dịch Do | Giả

public <T extends Number | CharSequence> void orDoer(T someData){ // ... } 

tức là thay vì viết nhiều chữ ký phương pháp, tôi muốn một phương pháp này để chấp nhận hoặc là một số hoặc CharSequence như một cuộc tranh cãi

nên Vượt qua với một số hoặc tham số CharSequence

orDoer(new Integer(6)); 
int somePrimitive = 4; 
orDoer(somePrimitive); 
orDoer("a string of chars"); 
+4

Bạn sẽ làm gì bên trong phương pháp mà không thể thực hiện với hai phương pháp riêng biệt chấp nhận 'Số' hoặc' CharSequence' tương ứng và sau đó ủy quyền cho phương pháp riêng tư thứ ba để thực hiện công việc? –

+1

Tôi đồng ý rằng lợi ích là không đáng kể nếu tôi đang xử lý hai loại, nhưng nó có vẻ là một cách ngắn gọn để ủy quyền nhiều loại tham số hơn (không chia sẻ siêu kiểu có thể sử dụng) – Cel

+1

Bạn nên xem [Ceylon] (http: // Các loại công đoàn của ceylon-lang.org/documentation/1.1/introduction/). ;) – Anonsage

Trả lời

16

Nếu bạn thực sự muốn thực hiện điều đó, bạn sẽ cần phải bọc các lớp được chấp nhận trong lớp tùy chỉnh của yo riêng của bạn. Trong trường hợp ví dụ của bạn, có thể là một cái gì đó như:

public class OrDoerElement { 
    private final Number numberValue; 
    private final CharSequence charSequenceValue; 

    private OrDoerElement(Number number, CharSequence charSequence) { 
     this.numberValue = number; 
     this.charSequenceValue = charSequence; 
    } 

    public static OrDoerElement fromCharSequence(CharSequence value) { 
     return new OrDoerElement(null, value); 
    } 

    public static OrDoerElement fromNumber(Number value) { 
     return new OrDoerElement(value, null); 
    } 
} 

Và phương pháp orDoer của bạn trở thành:

public void orDoer(OrDoerElement someData) { .... } 

Sau đó, bạn có thể xây dựng một trong những và sử dụng trong phương pháp của bạn bằng cách sử dụng:

orDoer(OrDoerElement.fromCharSequence("a string of chars")); 
orDoer(OrDoerElement.fromNumber(new Integer(6))); 

Nhưng thành thật mà nói, có vẻ hơi quá phức tạp và quá nhiều công việc chỉ để có thể gọi một phương thức với các kiểu tham số khác nhau. Bạn có chắc bạn không thể đạt được cùng một bằng cách sử dụng hai phương pháp, và một phương pháp thứ ba cho logic chung?

+0

Cảm ơn bạn đã trả lời! Tôi nhận ra bây giờ tôi đã không giải thích trường hợp sử dụng của tôi đúng - Tôi đang tìm kiếm một cái gì đó rất giống với 'T mở rộng ClassA | InterfaceB' bởi vì tôi muốn người gọi phương thức của tôi có thể truyền vào kiểu của họ như là (Integer hoặc String etc trực tiếp). Nghĩa là, để cung cấp một phương thức 'store (T data)', nó sẽ chấp nhận tất cả các kiểu có đặc tính của việc tái cấu trúc đầy đủ từ .toString() và một instantiation tham số đơn tiêu chuẩn (Number, CharSequence, Date và nhiều loại bền vững hơn). – Cel

+0

tức là một cách khác mà tôi có thể đặt câu hỏi là tại sao không có kiểu chia sẻ - trước Object - cho Number, CharSequence và các kiểu gốc khác, sẽ mô tả chúng như những Uniconstructables hoặc bất cứ thứ gì bạn muốn gọi chúng. có ý nghĩa) – Cel

+0

Vâng, tôi hiểu, loại siêu siêu hạng này thực sự hữu ích trong một số trường hợp – Guillaume

1

Có sử dụng lớp tóm tắt ẩn danh tùy chọn cho bạn không? Khi tôi cần loại thông số an toàn hoặc kiểu trả lại, tôi sử dụng một số biến thể của mã bên dưới. Điều đó đang được nói, tôi đồng ý với các ý kiến ​​khác ở đây, và tò mò những lợi ích bạn thực sự lấy được khi bạn thực thi một loại an toàn cho một nhóm các đối tượng không có nhiều điểm chung.

public abstract class Doer<T> { 

    public void do(T obj) { 
    // do some stuff. 
    } 

} 

// calling method 

new Doer<Number>(){}.do(new Integer(5)); 
+1

Cảm ơn, xin vui lòng xem phần giải thích dưới bài viết của Guillaume. – Cel

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