2012-04-13 59 views
6

Mã sau sử dụng khái niệm ghi đè phương pháp trong Java.Loại trả về biến đổi trong Java

package pkg; 

import java.util.ArrayList; 
import java.util.List; 

abstract class SuperClass 
{ 
    abstract public List<String>getList(); 
} 

final class SubClass extends SuperClass 
{ 
    private List<String>list=null; 

    @Override 
    public ArrayList<String> getList() 
    { 
     list=new ArrayList<String>(); 
     list.add("A"); 
     list.add("B"); 
     return (ArrayList<String>) list; 
    } 
} 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     SuperClass s=new SubClass(); 
     List<String>list=s.getList(); 

     for(String str:list) 
     { 
      System.out.println(str); 
     } 
    } 
} 

Theo quy ước, ghi đè phương thức sử dụng cùng chữ ký (với kiểu trả về) trong cả hai lớp siêu và lớp con. Trong đoạn mã trên, kiểu trả về của phương thức getList() trong SuperClassList và trong phân lớp của nó kiểu trả về là ArrayList. Phương pháp ghi đè tác phẩm ở đây như thế nào?

Nhân tiện, rõ ràng là ArrayList là triển khai giao diện List nhưng trình biên dịch xử lý kiểu trả về ở đây khi ghi đè phương pháp getList() như thế nào?

Tôi có nên tin điều gì đó như thế này không? Loại trả về của phương thức ghi đè được phép là loại phụ của loại trả về của phương thức được ghi đè.

+0

Có vẻ như không có lý do chính đáng để tuyên bố 'SubClass.list' như một' List' (chứ không phải là một 'ArrayList'). –

+0

@ MichaelBrewer-Davis - Nó có thể làm cho mọi thứ đẹp hơn khi bạn đang sử dụng 'SubClass' trực tiếp thay vì xử lý nó như một' SuperClass'. –

+0

@Brendan - Tôi đã nói về biến thành viên (tư nhân) quá chung chung, không phải là phương pháp quá cụ thể. Hiệp phương sai trong phương pháp là ánh nắng mặt trời và bướm. –

Trả lời

19

Có.

Trong java đầu không phải như vậy, nhưng nó đã được thay đổi trong Java 5.0.

Bạn không thể có hai phương thức trong cùng một lớp với chữ ký chỉ khác nhau theo loại trả về. Cho đến khi phát hành J2SE 5.0, nó cũng đúng là một lớp không thể ghi đè kiểu trả về của các phương thức mà nó thừa kế từ một lớp cha. Trong mẹo này, bạn sẽ tìm hiểu về một tính năng mới trong J2SE 5.0 cho phép các kiểu trả về biến đổi. Điều này có nghĩa là một phương thức trong một lớp con có thể trả về một đối tượng có kiểu là một lớp con của kiểu được trả về bởi phương thức có cùng chữ ký trong lớp cha. Tính năng này loại bỏ nhu cầu kiểm tra và truyền kiểu quá mức.

Nguồn thông tin này không còn khả dụng trên interwebs nữa.

+0

Liên kết đã chết. – Ghos3t

3

Vâng, đó là chính xác. Vì ArrayList là một List, bạn có thể trả về một ArrayList khi phương thức gốc trả về một List.

4

Trong lập trình hướng đối tượng, một kiểu trả về biến thể của phương thức là một kiểu có thể được thay thế bằng kiểu "hẹp hơn" khi phương thức được ghi đè trong một lớp con. Một ngôn ngữ đáng chú ý trong đó đây là một mô hình khá phổ biến là C++. kiểu trả về hiệp biến đã được (một phần) cho phép bằng ngôn ngữ Java từ việc phát hành JDK5.0, vì vậy ví dụ sau sẽ không biên dịch trên một phiên bản trước:

// Classes used as return types: 

class A { 
} 

class B extends A { 
} 

// "Class B is more narrow than class A" 
// Classes demonstrating method overriding: 

class C { 
    A getFoo() { 
     return new A(); 
    } 
} 

class D extends C { 
    B getFoo() { 
     return new B(); 
    } 
} 

Cụ thể hơn, hiệp biến (rộng đến hẹp) hoặc kiểu trả về (hẹp đến rộng hơn) cho biết tình huống mà kiểu trả về của phương thức ghi đè được thay đổi thành kiểu liên quan đến (nhưng khác với) kiểu trả về của phương thức ghi đè ban đầu.

Mối quan hệ giữa hai kiểu trả về biến đổi thường là một kiểu cho phép thay thế một kiểu với loại kia, theo nguyên lý thay thế Liskov.

Điều này thường ngụ ý rằng các kiểu trả về của các phương thức ghi đè sẽ là các kiểu con của kiểu trả về của phương thức ghi đè. Ví dụ trên minh họa cụ thể trường hợp này. Nếu không cho phép thay thế, kiểu trả về là bất biến và gây ra lỗi biên dịch.

tham khảo: https://en.wikipedia.org/wiki/Covariant_return_type

+0

https://en.wikipedia.org/wiki/Covariant_return_type –

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