2015-05-11 22 views
6

Giả sử các lớp sau đây không:Java Generic class mở rộng loại parametrized

class A { 
    public void foo() { ... }; 
    ... 
} 

class A1 extends A { ... }; 
class A2 extends A { ... }; 
... 
class A1000 extends A { ... }; 

bây giờ, chúng ta cần tạo một biến thể của mỗi lớp Axx đó sẽ ghi đè phương pháp "foo". Ý tưởng cơ bản là:

class B<T extends A> extends T { 
    @Override public void foo() { ... }; 
} 

Nhưng có vẻ như không thể mở rộng lớp học từ một trong các loại tham số của chúng.

Mục tiêu là để bỏ qua nhu cầu sau mã mới:

class B1 extends A1 { @Override public void foo() { ... }; }; 
class B2 extends A2 { @Override public void foo() { ... }; }; 
.... 
class B1000 extends A1000 { @Override public void foo() { ... }; }; 

và cho phép những câu như:

... 
B<A643> b643 = new B<A643>; 
b643.foo(); 
... 

Bất kỳ gợi ý?

Cảm ơn rất nhiều.

+2

Không nơi nào trong mã của bạn là tham số loại 'T' thực sự được sử dụng cho bất kỳ thứ gì, do đó bạn chỉ có thể loại bỏ nó khỏi mã của bạn hoàn toàn. Ngoài ra, nếu 'T' thực sự là một tham số kiểu chính thức, thì' B extends T' không hợp lệ. – scottb

+0

Mục tiêu là bỏ qua sự cần thiết của mã mới sau đây: lớp B1 mở rộng A1 {Override public void foo() {...}; }; lớp B2 mở rộng A2 {Override public void foo() {...}; }; ... lớp B1000 mở rộng A1000 {Override public void foo() {...}; } ;. Làm rõ về câu hỏi. –

+0

Tôi cảm thấy như những gì OP đang cố gắng làm là có một cách phổ biến để mở rộng bất kỳ loại nhất định với việc thực hiện này 'foo'. Ví dụ, 'A1',' A2', ... 'A1000' là hoàn toàn (hoặc chủ yếu) không liên quan và mỗi phương thức riêng của chúng, và' B1', 'B2', ...' B1000' tương tự không liên quan, mỗi phương thức có cùng một phương thức giống như các đối tác 'Annn' * của chúng cũng như * thực hiện phổ biến này của' foo' (có thể hoặc không thể ghi đè hoặc sử dụng các thành viên được bảo vệ của 'A'). – TheHansinator

Trả lời

0

Cuối cùng, được giải quyết bằng lớp proxy. Phản ánh tiêu chuẩn.proxy không được áp dụng, nhưng proxy từ thư viện CGLib thì không. Trong ngắn hạn, một kẻ đánh chặn với cùng một mã hơn "B.foo" được sử dụng. Xem reflection.proxy not valid when override để biết chi tiết. Cám ơn Tagir Valeev vì sự giúp đỡ của anh ấy.

5

A không phải là chung chung. Tôi nghĩ rằng bạn muốn một cái gì đó như thế nào,

class B<T> extends A { 
    @Override public void foo() { ... }; 
} 

Đó là một kiểu generic B kéo dài A ... T extends A có nghĩa B mất một loại kéo dài A (không B kéo dài A).

+0

Xin chào, cảm ơn sự cộng tác của bạn. Mục tiêu là bỏ qua nhu cầu viết một cái gì đó như "lớp B1 mở rộng A1 ...", "lớp B2 mở rộng A2 ..." với một "lớp B" chung chung giống như một chương trình trong câu hỏi. Lớp chung là "B" và "A1" ... "A1000" là các tham số kiểu. –

+0

@Alu không thể có trong java. –

+0

thiết bị đo đạc và nội tâm? –

1

Bạn có thể kết hợp kế thừa với ủy quyền. Tôi sẽ xem xét nó xấu xí, nhưng nó sẽ làm việc.

class UniversalB extends A{ 
A a; 
UniversalB(A a) { 
    this.a = a; 
} 

@Override public void foo() { ... }; 

// @Override any other method from A you want/need 
// and delegate it to the passed member if necessary 

} 

UniversalB b = new UniversalB(new A123()); 
b.foo(); 
b.anyMethodInA(); 
+0

Xin chào. Cảm ơn sự cộng tác của bạn. Vấn đề trong đề xuất của bạn là khi A123 gọi "foo()" trong một số phương thức ban đầu của nó. Nó sẽ sử dụng triển khai A123 của foo, thay cho phiên bản mới tại "UniversalB". –

+1

Thật vậy. Nhưng không thể tạo ra một lớp có hệ thống phân cấp không xác định thời gian động, biên dịch. Các mẫu được xác minh tại thời gian biên dịch, nhưng, theo như tôi nhớ, thực tế đã bỏ qua thời gian chạy. Đó là loại đường cú pháp xác minh mã. – Dariusz

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