java中的上帝類:Object
問:什麼是Object類?java
答:Object類存儲在java.lang包中,是全部java類(Object類除外)的終極父類。固然,數組也繼承了Object類。然而,接口是不繼承Object類的,Object類不做爲接口的父類。java的任何類都繼承了這些函數,而且能夠覆蓋不被final修飾的函數。例如,沒有final修飾的toString()函數能夠被覆蓋,可是final wait()函數就不行。
問:能夠聲明要「繼承Object類」嗎?數組
答:能夠。在代碼中明確地寫出繼承Object類沒有語法錯誤。
例如:ide
importjava.lang.Object; publicclassEmployee extendsObject { privateString name; publicEmployee(String name) { this.name = name; } publicString getName() { returnname; } publicstaticvoidmain(String[] args) { Employee emp = newEmployee("John Doe"); System.out.println(emp.getName()); } }
你能夠試着編譯代碼1(javac Employee.java),而後運行Employee.class(java Employee),能夠看到John Doe 成功的輸出了。函數
由於編譯器會自動引入java.lang包中的類型,即 import java.lang.Object; 不必聲明出來。Java也沒有強制聲明「繼承Object類」。若是這樣的話,就不能繼承除Object類以外別的類了,由於java不支持多繼承。然而,即便不聲明出來,也會默認繼承了Object類。
默認繼承Object類例如:flex
publicclassEmployee { privateString name; publicEmployee(String name) { this.name = name; } publicString getName() { returnname; } publicstaticvoidmain(String[] args) { Employee emp = newEmployee("John Doe"); System.out.println(emp.getName()); } }
Equality
問:euqals()函數是用來作什麼的? 答:equals()函數能夠用來檢查一個對象與調用這個equals()的這個對象 是否相等。
問:爲何不用「==」運算符來判斷兩個對象是否相等呢? 答:雖然「==」運算符能夠比較兩個數據是否相等,可是要來比較對象的話, 恐怕達不到預期的結果。就是說,「==」經過是否引用了同一個對象來判斷兩 個對象是否相等,這被稱爲「引用相等」。這個運算符不能經過比較兩個對象 的內容來判斷它們是否是邏輯上的相等。
問:使用Object類的equals()方法能夠用來作什麼樣的對比? 答:Object類默認的eqauls()函數進行比較的依據是:調用它的對象和傳入的 對象的引用是否相等。也就是說,默認的equals()進行的是引用比較。若是兩 個引用是相同的,equals()函數返回true;不然,返回false.
問:覆蓋equals()函數的時候要遵照那些規則? 答:覆蓋equals()函數的時候須要遵照的規則在Oracle官方的文檔中都有申明: 1. 自反性:對於任意非空的引用值x,x.equals(x)返回值爲真。 2. 對稱性:對於任意非空的引用值x和y,x.equals(y)必須和 y.equals(x)返回相同的結果。 3. 傳遞性:對於任意的非空引用值x,y和z,若是x.equals(y)返回真, y.equals(z)返回真,那麼x.equals(z)也必須返回真。 4. 一致性:對於任意非空的引用值x和y,不管調用x.equals(y)多少次, 都要返回相同的結果。在比較的過程當中,對象中的數據不能被修改。 5. 對於任意的非空引用值x,x.equals(null)必須返回假。
問:能提供一個正確覆蓋equals()的示例嗎? 答:固然能夠,例如: class Employee{ private String name; private int age; Employee(String name, int age){ this.name = name; this.age = age; } @Override public boolean equals(Object o){ if( ! ( o instanceofEmployee)){ return false; } Employee e = (Employee) o; return e.getName().equals(name) && e.getAge() == age; } String getName(){ return name; } int getAge(){ returnage; } } public class EqualityDemo{ public static void main(String[] args){ Employee e1 = newEmployee("John Doe", 29); Employee e2 = newEmployee("Jane Doe", 33); Employee e3 = newEmployee("John Doe", 29); Employee e4 = newEmployee("John Doe", 27+2); // 驗證自反性。 System.out.printf("Demonstrating reflexivity...%n%n"); System.out.printf("e1.equals(e1): %b%n", e1.equals(e1)); // 驗證對稱性。 System.out.printf("%nDemonstrating symmetry...%n%n"); System.out.printf("e1.equals(e2): %b%n", e1.equals(e2)); System.out.printf("e2.equals(e1): %b%n", e2.equals(e1)); System.out.printf("e1.equals(e3): %b%n", e1.equals(e3)); System.out.printf("e3.equals(e1): %b%n", e3.equals(e1)); System.out.printf("e2.equals(e3): %b%n", e2.equals(e3)); System.out.printf("e3.equals(e2): %b%n", e3.equals(e2)); // 驗證傳遞性。 System.out.printf("%nDemonstrating transitivity...%n%n"); System.out.printf("e1.equals(e3): %b%n", e1.equals(e3)); System.out.printf("e3.equals(e4): %b%n", e3.equals(e4)); System.out.printf("e1.equals(e4): %b%n", e1.equals(e4)); // 驗證一致性。 System.out.printf("%nDemonstrating consistency...%n%n"); for(inti = 0; i < code>5; i++){ System.out.printf("e1.equals(e2): %b%n", e1.equals(e2)); System.out.printf("e1.equals(e3): %b%n", e1.equals(e3)); } // 驗證傳入非空集合時,返回值爲false。 System.out.printf("%nDemonstrating null check...%n%n"); System.out.printf("e1.equals(null): %b%n", e1.equals(null)); } }
toString:
public String toString():返回該對象的字符串表示。this
toSting方法返回該對象的字符串表示,其實該字符串內容就是對象的類型+@+內存地址值。idea
因爲toString方法返回的結果是內存地址,而在開發中,常常須要按照對象的屬性獲得相應的字符串表現形式,所以也須要重寫它。code
若是不但願使用toString方法的默認行爲,則能夠對它進行覆蓋重寫。例如: public class Person { private String name; private int age; @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } // 省略構造器與Getter Setter }
在idea中,能夠點擊菜單中的Generate,也能夠使用快捷鍵alt+insert,點擊toString的選項。對象
Tips:在咱們直接使用輸出語句輸出對象名的時候,其實經過該對象調用了其toString的方法。