class A{ public int i; public A(int i){ // 構造函數 this.i = i; } } public class TestEq{ public static void main(String[] args){ A aa1 = new A(2); B aa2 = new A(2); System.out.println(aa1.equlas(aa2)); //false } }
爲何是這樣?java
若是咱們單獨函數
System.out.println(aa1); -> 前面A表示類 @後面跟着的是這個對象在內存中地址16進制的表示 System.out.println(aa2);
很明顯不是同一個對象,若是是同一個對象那麼地址也能夠說指針吧,確定是同樣的,不同是由於this
在內存中咱們開闢了4個內存,aa1,aa2 在棧中,分別指向了堆中一個new A(2) , 一個new A(2)指針
這樣兩個對象不相等那是理所固然的了code
那之後咱們可能會寫一些容器之類的東西,把一些類丟進去,重複的就不要了,那咱們能夠對象
class A{ public int i; public A(int i){ this.i = i; } public boolean equals(Object obj){ A aa = (A)obj; if(aa.i == this.i) return true; else return false; } } public class testB{ public static void main(String[] args){ A aa1 = new A(2); A aa2 = new A(2); System.out.println(aa1.equals(aa2)); //true } }
那爲何重寫父類的equlas的時候加上繼承
A aa = (A)obj //這句 就能夠了?
舉個簡單例子內存
class A{ //父類 void f(){ System.out.printf("AAAAA\n"); } } class B extends A{ 子類繼承父類A void f(){ System.out.printf("BBBBB\n"); } void g(){} } public class testPloy{ public static void main(String[] args){ A aa = new A(); B bb = new B(); aa.f()//success, 由於父類能夠調用子類繼承本身的東西 aa.g()//error ,由於父類沒法調用子類所特有的東西 //假如把子類bb的指針發送給父類aa呢 aa = bb aa.g()//error //那惟有經過強制轉換 B bb2 = (B)aa; bb2.g() //success //強制轉換必須有個先確條件就是 aa=bb,必須是父類已經指向了子類才行 } }
因此回頭在看這個重寫的equalsclass
aa1.equals(aa2);
咱們把aa2發送給父類 Object obj 就至關於test
obj = aa2
因此能夠經過強制轉換
A aa = (A)obj
達到訪問子類因此特有的屬性方法
若是把
if(aa.i == this.i) //改爲 if(obj.i == this.i)
答案是會報錯,由於前面說了,父類的對象是不能夠直接訪問子類對象所特有的屬性方法~!