2015-06-07 15 views
5

Bất cứ ai có thể giải thích cho tôi về kết quả của việc thực thi này không? Tôi không thể nhận thấy tại sao mỗi phương pháp được gọi. Và cách chúng tôi phân biệt loại thực so với loại rõ ràng. Cảm ơn bạn :)Thừa kế trong Java, loại rõ ràng so với loại thực tế

public class JavaApplication15 { 
    public static void main(String[] args) { 
     A a = new A(); 
     B b= new B(); 
     A ab = new B(); 
     b.f(a); 
     b.f(b); 
     b.f(ab); 
    } 
} 

public class A { 
    private final String id="A"; 
    public void f(A x){ 
    System.out.println("Send a fax to "+ x) ; 
    } 
    public String toString(){return id;} 
} 

public class B extends A{ 
    private final String id="B"; 
    public void f(B x){ 
    System.out.println("Send an email to"+ x) ; 
    } 
    public String toString(){return id;} 
} 

Kết quả:

Send a fax to A 
Send an email to B 
Send a fax to B 

Trả lời

3

Bạn đang overloading mà (theo wikipedia) tạo nhiều phương pháp cùng tên với hiện thực khác nhau. Tôi nghĩ rằng bạn có nghĩa là để override phương pháp f(A x) với phương pháp f(B x). Ghi đè (theo wikipedia) cho phép lớp con hoặc lớp con cung cấp triển khai cụ thể phương thức đã được một trong các lớp cha hoặc lớp cha của nó cung cấp.

Dựa trên sự ngạc nhiên thể hiện trong câu hỏi của bạn, tôi nghĩ rằng bạn muốn một cái gì đó giống như

@Override 
public void f(A x) { 
    System.out.println("Send an email to"+ x) ; 
} 
2
@Override 
public String toString() 
{ 
    return id; 
} 

này định nghĩa cách lớp được outputted. Khi bạn gọi một chức năng như sau:

b.f(a) 

Bạn đang nhập một lớp làm tham số. Do phương pháp toString() của bạn, phương pháp này là cách ghi đè phương thức chuẩn để xuất lớp của bạn, bạn hiển thị id sau Send an email to.

1

B mở rộng A và A có phương pháp công khai. Vì vậy, nó có cả hai phương pháp sau đây -

public void f(A x){ 
    System.out.println("Send a fax to "+ x) ; 
} 

Và -

public void f(B x){ 
    System.out.println("Send an email to"+ x) ; 
} 

Trên thực tế phương pháp seond trong B là một phiên bản quá tải của phương pháp void f(A x) thừa hưởng từ A

2

mỗi object của class B có cả hai số f(A)f(B). Khi bạn gọi số f(x), thông thường, hãy chọn loại cụ thể nhất phù hợp với loại x. Đối với điều này, điều quan trọng là loại tài liệu tham khảo .

Vì vậy, aA, do đó, nó gọi số f(A). Số điện thoại b của bạn là B, do đó, số này gọi là f(B). Nhưng ab của bạn là gì? Loại tham chiếu là A. Vì vậy, trình biên dịch bảo nó gọi là quá tải f(A).

Nhưng sau đó, không nên nó đã sử dụng các đối tượng ab như một A và do đó in send a fax to A sử dụng A.toString() hơn B.toString()?

Không, bởi vì lựa chọn phương thức được gọi trong trường hợp này không được xác định bởi tham số.Nó không phải là một sự lựa chọn giữa quá tải như sự lựa chọn ở trên, nó là một sự lựa chọn giữa ghi đè. Khi quyết định phương thức nào sẽ sử dụng, phương thức từ siêu lớp hoặc phương thức từ lớp con, loại thực tế là đối tượng sẽ xác định phương thức đó. Vì đối tượng được đề cập bởi ab thực ra là một số B, nên chọn toString() trong số B.

Vì vậy - trong số quá tải phương pháp, một trong đó là lựa chọn được xác định dựa trên số lượng và loại của các đối số, và các loại đối số là loại của tham khảo.

Trong số ghi đè phương thức, phương thức được chọn là phương thức trong loại thực tế của đối tượng đối tượng, bất kể loại tham chiếu mà thông qua đó được gọi.

Lưu ý rằng một phương pháp chỉ được coi là ghi đè nếu nó có cùng tên, số tham số và loại tham số tương ứng làm phương thức gốc.

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