1. 程式人生 > >java.lang.Object(陣列收集物件&重新定義)

java.lang.Object(陣列收集物件&重新定義)

在Java中,子類只能繼承一個父類,如果定義類時沒有使用 extends關鍵字指定繼承任何類,那一定是繼承java.lang. object也就是說,如果這樣定義類:

public class Some{
...
}

那就相當於撰寫:

public class Some extends Object{
}

因此在Java中,任何類追溯至最上層父類一定就是java.lang. Object,也就是Java中所有物件,一定“是一種” object,所以這樣撰寫程式是合法的:

Object o1="李白"Object o2=new Date();

String是一種 object,Date是一種 object,任何型別的物件,都可以使用 oblect宣告的名稱來參考。這有什麼好處?如果有個需求是使用陣列收集各種物件,那該宣告 object[]。例如:

Object[] objs= {"李白",new Date(),new SwordsMan()};
    String name=(String) objs[0];
    Date date=(Date) objs[1];
    ...

因為陣列長度有限,使用陣列來收集物件不是那麼方便,以下定義的 Arraylist類,可以不限長度地收集物件:

package hello;

import java.util.Arrays;

public class ArrayList {
    private Object[] list;
    private int next;

    public
ArrayList(int capacity) { list=new Object[capacity]; } public ArrayList() { this(3); } public void add(Object o) { if(next==list.length) { list=Arrays.copyOf(list, list.length*2); } list[next++]=o; } public Object get(int index) { return
list[index]; } public int size() { return next; } }

自定義的 Arraylist類,內部使用 Object陣列來收集物件0,每一次收集的物件會放在next指定的索引處,在建立 Arraylist例項時,可以指定內部陣列初始容量,如果使用無引數建構函式,則預設容量為3。如果要收集物件,可通過add()方法,注意引數的型別為 Object,可以接收任何物件如果內部陣列原長度不夠,就使用 Arrays. copyof()方法自動建立原長度兩倍的陣列並複製元素⊙。如果想取得收集的物件,可以使用get()指定索引取得。如果想知道己收集的物件個數,則通過size()方法得知。
以下使用自定義的 Arraylist類,可收集訪客名稱,並將名單轉為大寫後顯示:

package hello;

import java.util.*;
import static java.lang.System.*;

public class Guest {
    public static void main(String[] args) {
        ArrayList datas=new ArrayList();
        collectDataTo(datas);
        out.println("訪客名單:");
        printUpperCase(datas);
    }

    private static void collectDataTo(ArrayList datas) {
        Scanner scan=new Scanner(System.in);
        while(true) {
            out.println("訪客名單");
            String data=scan.nextLine();
            if(data.equals("*")) {
                break;
            }
            datas.add(data);
        }
    }

    private static void printUpperCase(ArrayList datas) {
        for(int i=0;i<datas.size();i++) {
            String data =(String) datas.get(i);
            out.println(data.toUpperCase());
        }
    }
}

java.lang.Object是所有類的頂層父類,Object上的方法只要不是被定義為final,都可以重新定義。
1、toString()
object的toString()預設定義為:

public String toString(){
    return getClass().getName()+"@"+Integer.toHexString(hashCode());
}

返回的字串包括類名稱以及十六進位制雜湊碼,許多方法如果傳入物件,預設都會呼叫toString()。如System.out.print()方法就會呼叫toString()以取得字串描述來顯示:

System.out.println(swordsMan.toString);
//就是
System.out.println(swordsMan);

2.重新定義 equals()
在Java中要比較兩個物件的實質相等性,並不是使用=,而是通過 quals方法,在後續你看過 Integer等打包,以及字串相等性比較時,都是使用 equals()方法。實際上 equals()方法是 Object類有定義的方法,其程式程式碼是:

public boolean equals(object obj){
    return (this==obj);
}

如果沒有重新定義 equals(),使用 equals0方法時,作用等同於=,所以要比較實質相等性,必須自行重新定義。如:

package hello;

public class Cat {
    //......

    public boolean equals(Object other){
        if(this==other) {//如果other參考的就是這個物件肯定是同一物件。
            return true;
        }
        //如果other參考的物件不是Cat創建出來的就是flase
        if(!(other instanceof Cat)) {
            return false;
        }else if(!getName().equals(cat.getName())){
            return false;//名字是否相同
        }else if(!getBirthDay().equals(cat.getBirthDay())){
            return false;//生日是否相同
        }

        return true;
    }
}

這個程式片段示範了 equals()操作的基本概念。這裡也看到了 instanceof運算子,它可以用來判斷物件是否由某個類建立,左運算元是物件右運算元是類,在使用 instanceof時,編譯程式還會來幫點忙,會檢查左運算元型別是否在右運算元型別的繼承架構中(或介面操作架構中)
執行時期,並非只有左運算元物件為右操數類直接例項化才返回true,只要左運算元型別是右運算元型別的子型別, instanceof也是返回true
這裡僅示範了 equals()操作的基本概念,實際上操作equals()並非這麼簡單。操作 equals()時通常也會操作 hashcode()。