2017-10-21 14 views
5

Ví dụ tôi có một lớp cơ sở xử lý với một phương thức trả về một đối tượng và lấy Object làm tham số. Tôi muốn mở rộng nó và tạo ra một StringProcessor sẽ trả về String và lấy String làm tham số. Tuy nhiên, chỉ có thể cho phép nhập biến đổi với giá trị trả về, chứ không được phép tham số. Lý do cho những hạn chế như vậy là gì?Tại sao phương pháp ghi đè java cho phép có các kiểu trả về biến đổi, nhưng không phải là các tham số covariant?

class Processor { 
    Object process (Object input) { 
     //create a copy of input, modify it and return it 
     return copy; 
    } 
} 

class StringProcessor extends Processor { 
    @Override 
    String process (String input) { // permitted for parameter. why? 
     //create a copy of input string, modify it and return it 
     return copy; 
    } 
} 

Trả lời

10

The Liskov principle. Khi thiết kế lớp Processor, bạn viết một hợp đồng cho biết: "một Processor có thể lấy bất kỳ đối tượng nào làm đối số và trả về một đối tượng".

Trình xử lý chuỗi là bộ xử lý. Vì vậy, nó phải tuân theo hợp đồng đó. Nhưng nếu nó chỉ chấp nhận String làm đối số, nó vi phạm hợp đồng đó. Hãy nhớ rằng: một bộ xử lý được cho là chấp nhận bất kỳ đối tượng nào làm đối số.

Vì vậy, bạn sẽ có thể làm:

StringProcessor sp = new StringProcessor(); 
Processor p = sp; // OK since a StringProcessor is a Processor 
p.process(new Integer(3456)); 

Khi trả về một String, nó không vi phạm hợp đồng: đó là nghĩa vụ phải trả lại một đối tượng, một String là một đối tượng, vì vậy mọi thứ đều tốt.

Bạn có thể làm những gì bạn muốn đạt được bằng cách sử dụng Generics:

class Processor<T> { 
    Object process (T input) { 
     //create a copy of input, modify it and return it 
     return copy; 
    } 
} 

class StringProcessor extends Processor<String> { 
    @Override 
    String process (String input) { 
     return copy; 
    } 
} 
0

Ngoài ra, nếu bạn muốn có một câu trả lời kiểu lý thuyết, lý do cho điều này là, khi xem xét mối quan hệ subtyping trên các loại chức năng, mối quan hệ là hiệp biến trên các loại trở lại, nhưng contravariant trên loại đối số (ví dụ X -> Y là một subtype của U -> W nếu Y là một subtype của WU là một subtype của X).

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