2013-02-23 52 views
6

Tôi đang cố gắng triển khai và ghi đè phương thức với các loại trả về khác nhau mà không bị ép buộc loại trả về.Các kiểu trả về khác nhau của phương thức trừu tượng trong java mà không cần đúc

public abstract class A { 
public abstract Object getValue(String content); 
} 

public class B extends A { 
public String getValue(String content) {...} 
} 

public class C extends A { 
public int getValue(String content) {...} 
} 


public class D extends A { 
public boolean getValue(String content) {...} 
} 

// Main loop: 
for (A a : allAs) 
{ 
// I want to use the method getValue() and corresponding to the type return a String, int or boolean without casting the return type 
} 

Câu hỏi của tôi: Có thể trả lại các loại khác nhau mà không bị ép buộc không? Phương pháp trừu tượng trông như thế nào để giải quyết vấn đề?

Tôi nghĩ rằng phải có giải pháp vì trình biên dịch phải biết kiểu trả về ...

+0

Bạn không thể ghi đè dựa trên loại trả lại. –

+0

Và chương trình này sẽ không biên dịch –

Trả lời

13

Trong ví dụ của bạn, các lớp CD sẽ không biên dịch. Các phương thức ghi đè trong chúng vi phạm Liskov substitution principle, hay còn gọi là kiểu trả về của chúng không tương thích với lớp cha của chúng. Những gì bạn đang tìm kiếm để làm có thể được thực hiện với generics, miễn là bạn sẵn sàng từ bỏ việc sử dụng các nguyên thủy như là kiểu trả về của bạn.

abstract class A<T> { 
    public abstract T getValue(String content); 
} 

class B extends A<String> { 
    public String getValue(String content) { } 
} 

class C extends A<Integer> { 
    public Integer getValue(String content) { } 
} 

class D extends A<Boolean> { 
    public Boolean getValue(String content) { } 
} 
+0

Cảm ơn. Mã này có thể hoạt động. Tuy nhiên kiểu trả về của getValue() là một "đối tượng" để tôi phải bỏ nó. – erwingun2010

+0

@ erwingun2010 Nếu phương thức của bạn có kiểu trả về 'Object', bạn có thể khởi tạo lớp sai. Thực hiện điều này: 'A bInstance = new B();' Nếu bạn không thêm kiểu vào khai báo A, các phương thức trừu tượng của bạn sẽ trả về 'Object'. – fiskeben

3

Điều bạn mô tả là không thể nói chung. Tuy nhiên, nếu lớp con trả về một kiểu con "hẹp hơn" của phương thức trả về siêu lớp, thì đây được gọi là "kiểu trả về biến đổi" và được cho phép trong Java kể từ JDK 1.5. Tuy nhiên, dựa trên ví dụ của bạn tôi không nghĩ rằng sự trở lại biến đổi là những gì bạn đang tìm kiếm.

tôi giả sử những gì bạn muốn là

for (A a : allAs) 
{ 
    String b = a.getValue(); 
    int c = a.getValue(); 
} 

Vấn đề ở đây là, tất nhiên, rằng trình biên dịch không có cách nào biết tại thời gian biên dịch mà của hai báo cáo là đúng, và họ có thể không được cả hai đúng.

+0

Đó chính là điều tôi muốn. Tôi vẫn không hiểu tại sao trình biên dịch không thể biết tại thời gian biên dịch mà kiểu trả về là chính xác. Khi tôi khởi tạo allAs tôi sử dụng => allAs.add (new B()); allAs.add (new C()); – erwingun2010

+0

Trong ví dụ tôi đã trình bày, cả hai câu lệnh bên trong vòng lặp đều tham chiếu đến một thể hiện _single_ của 'A', không thể là cả hai' B' và 'C' cùng một lúc. Làm thế nào là trình biên dịch phải biết đó là vì điều đó không xảy ra cho đến khi thời gian chạy? –

0

Trong ví dụ của bạn, định nghĩa về class B là ok, vì String là một lớp con của Object. Hai người kia sẽ không biên dịch, vì chúng là các kiểu nguyên thủy. Bạn có thể thay thế chúng bằng IntegerBoolean quay lại để giải quyết điều đó.

Đối với vòng lặp chính của bạn, nếu bạn đang lặp lại chúng dưới dạng tham chiếu đến A, bạn sẽ chỉ có thể sử dụng định nghĩa của phương pháp A, trả về Object.

2

Bạn có thể sử dụng Generics.

public abstract class A<T> { 
    public abstract T getValue(String content); 
} 

public class B extends A<String> { 
    public String getValue(String content) {...} 
} 

etc ... int không hoạt động như kiểu trả về cho điều này, nhưng số nguyên sẽ.

Tôi không gõ vào một trình biên dịch nên có thể có lỗi chính tả ...

Theo ghi nhận của Jim và Chris, nếu bạn đang Looping trên As, bạn có thể chỉ nhận được "A" kết quả, đó là Vật.

+0

Cảm ơn. Để chắc chắn tôi phải sử dụng chuỗi gốc, Boolean, Integer, .... – erwingun2010

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