2013-05-11 26 views
5

Tôi có câu hỏi về cách ghi đè phương thức equals trong Java. Trong cuốn sách của tôi, tôi có ví dụ sau:Truyền bằng phương thức equals

public class Dog{ 
    private String name; 
    private int age; 

public boolean equals(Object obj) { 
    if(!(obj instanceof Dog)) return false; 
    Dog other = (Dog) obj;     ---> confused here 
    if(this.name.equals(other.name) && (this.age == other.age) { 
    return true; 
    } 
    else { 
    return false; 
    } 
    } 
} 

Tôi không hiểu tại sao tại sao phải bỏ tham chiếu đến Dog tham khảo. Nếu tham chiếu đó không thuộc loại Dog, chúng tôi trả về false. Tại sao tất cả các rắc rối với đúc nó?

+0

Đừng quên obj == null. Và không liên quan đến câu hỏi của bạn nhưng bạn chỉ có thể trả về this.name.equals (other.name) && (this.age == other.age) – ssedano

+0

Vì Equals này chỉ chấp nhận một tham số và đây là ghi đè lên lớp Dog điều này bằng mong đợi đối tượng của loại Dog. nếu bạn vượt qua một loại đối tượng sau đó sẽ luôn luôn trả về false này là một phần của chương trình cực đoan đó là để đảm bảo tránh bất kỳ lỗi thời gian chạy dự kiến. –

+2

Sẽ đơn giản hơn để trả lời câu hỏi này nếu bạn có thể đề xuất cách bạn sẽ * thích * để viết mã mà không có dàn diễn viên, lưu ý rằng kiểu biên dịch 'obj' là' Đối tượng'. –

Trả lời

5

Loại được khai báo là objObject, vì vậy bạn phải truyền nó để báo cho trình biên dịch biết đó là Dog.

Mặc dù một cách hợp lý nó không thể là bất cứ điều gì khác tại thời điểm đó trong mã, trình biên dịch không biết gì về logic - nó chỉ biết về loại.

+0

Sự thật được nói, trình biên dịch * có thể * biết về nó trong trường hợp đơn giản này. –

+1

@MarkoTopolnik Trình biên dịch có thể thực hiện rất nhiều thứ, nhưng một cách để vẽ đường dây ở đâu đó ... – Bohemian

+2

Thật vậy, mặc dù các ngôn ngữ khác nhau vẽ đường khác nhau. Ví dụ, trong Ceylon, dàn diễn viên [sẽ không cần thiết] (http://ceylon-lang.org/documentation/1.0/tour/types/). – meriton

4

Vì bạn đang xác định các tham số của riêng bạn cho sự bình đẳng, bạn phải đảm bảo chúng là cùng một lớp. Tức là, trừ khi bạn so sánh chúng theo cách ==, thì bạn cần phải so sánh một số giá trị bên trong các đối tượng. Để so sánh các giá trị bên trong các đối tượng, chúng cần phải cùng loại!

Ví dụ: giả sử bạn có hai số Dog s.

Dog dog1 = new Dog("Fido"); 
Dog dog2 = new Dog("Rover"); 

Nếu bạn muốn kiểm tra nếu họ có cùng tên, như tôi chắc chắn rằng bạn biết, bạn không thể sử dụng:

if(dog1 == dog2) 

Vì vậy, bạn ghi đè lên bằng phương pháp. Tuy nhiên, bởi vì bạn đang ghi đè nó, nó phải có cùng một chữ ký phương thức . Chữ ký phương thức được xác định bằng tên của phương thức, và số lượng và loại tham số của nó. Có nghĩa là nếu bạn muốn ghi đè nó, nó cần phải có một tham số kiểu Object. Do đó:

if(dog1.equals(dog2)) 

Lý do bạn cần phải cast nó để sử dụng bất cứ phương pháp nào bạn đang sử dụng để có được giá trị name từ con chó, và so sánh những giá trị đó.

Một lưu ý về thiết kế lớp học của bạn

Quy ước trong lập trình hướng đối tượng, và chắc chắn trong Java, là phải có AccessorMutator phương pháp để có được và thay đổi các biến trong một lớp học. Đó là:

dog1.name; ----> dog1.getName(); 

nơi getName() trông giống như:

public String getName() 
{ 
    return name; 
} 
0

Bạn đang trọng bằng phương pháp để kiểm tra bình đẳng bởi valuekhông bởi reference ..

tức Bạn muốn hai con chó bằng nhau nếu họ có cùng mộtnameagekhông nếu họ được sở hữu bởi cùng một người (tức là không nếu tài liệu tham khảo của họ đều bình đẳng)


Nếu không có diễn viên bạn không thể truy cập con chó của nameage thành viên

0

Đối với JVM nó không phải là rõ ràng obj là Chó, vì vậy bạn phải rõ ràng với dàn diễn viên.

0

Vì tham số phương thức obj là trường hợp của lớp Object.Vì vậy, trong phần thân phương thức, bạn cần phải đúc obj quay lại loại Dog.

0

Các thuộc tính nameage chỉ dành riêng cho Dog. Bạn không thể truy cập name hoặc age bằng cách sử dụng obj, là Object. Đối với ex, đoạn mã sau sẽ tạo ra compile time error:

this.name.equals(obj.name) 

Tôi không hiểu tại sao tại sao phải bỏ các tham chiếu đến các tài liệu tham khảo Dog. Nếu tham chiếu đó không thuộc loại Dog, chúng ta trả về false. Tại sao tất cả các rắc rối với đúc nó?

Bởi vì mặc dù tham chiếu là Dog nó không có nghĩa là nó giống với Chó. Tên của chú chó khác có thể không giống với tên của bạn Dog. Để so sánh nameage của Dog khác với Dog của bạn, trước tiên nó phải được truyền trước.

0

Tôi nghĩ rằng lớp demo của bạn thiếu phương thức hashCode(). Hai đối tượng chỉ có thể bằng nhau nếu cuộc gọi của chúng đến một hashCode() được ghi đè bằng nhau. (cùng giá trị số nguyên).

Tôi chắc chắn bạn cần cả hai để đảm bảo phương trình này.