JAVA基礎類庫--Object

Object類用於統一對象、數組和接口。

Object類基本描述

1、Object類是所有類的父類,即任何一個類在沒有定義繼承某個類時,Object類就是其父類。

class Book{}	
class Book extends Object{}

上述兩個類聲明是等價的,Object類是唯一沒有父類的類。Object類是所有類的父類,因此可以利用Object類通過向上轉型,接收所有類型的對象。

class Book extends Object {
}

public class Demo {
    public static void main(String[] args) {
        Object objA = new Book(); // 向上轉型
        Object objB = "Hello"; // 向上轉型
        Book b = (Book) objA; // 向下轉型
        String s = (String) objB; // 向下轉型
    }
}

因此在不確定參數類型時,使用Object類型是最好的選擇。
2、Object類中定義了一個無參構造方法,因爲其是所有類的父類,所以實例化子類對象時必然會調用父類的無參構造方法。

一般而言,定義簡單Java類時應覆寫Object類中的如下方法:
· 取得對象信息:public String toString();
· 對象比較:public boolean equals(Object obj);
· 取得對象HASH碼:public int hashCode();

toString()

class Book extends Object {
}

public class Demo {
    public static void main(String[] args) {
        Book b = new Book();
        String s = "Hello";
        System.out.println(b); // Book@1540e19d
        System.out.println(b.toString()); // Book@1540e19d
        System.out.println(s); // Hello
    }
}

上述代碼中直接輸出實例對象和使用toString()輸出的結果是一樣。因爲輸出對象時,會自動調用toString()將對象變爲字符串後輸出。Object類中的toString()爲了適應對象的輸出,僅輸出對象的編碼。
但是這和我們的想法不符,我們想輸出的應該是實例化對象的屬性信息,因此要覆寫toString()。
範例:覆寫toString()

class Book extends Object {
    private String title;
    private double price;

    // getter,setter,無參構造方法暫時略
    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    public String toString() {
        return "書名:" + this.title + ",價格:" + this.price;
    }
}

public class Demo {
    public static void main(String[] args) {
        Book b = new Book("Java開發", 20.3);
        System.out.println(b); // 書名:Java開發,價格:20.3
    }
}

此時直接輸出對象,調用的就是覆寫後的方法。

equals()

範例:對象比較

class Book extends Object {
    private String title;
    private double price;

    // getter,setter,無參構造方法暫時略
    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    public String toString() {
        return "書名:" + this.title + ",價格:" + this.price;
    }

    public boolean equals(Object obj) {
        if (this == obj) { // 地址相同
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Book)) { // 不是Book類對象
            return false;
        }
        Book book = (Book) obj;
        if (this.title.equals(book.title)
                && this.price == book.price) {
            return true;
        }
        return false;
    }
}

public class Demo {
    public static void main(String[] args) {
        Book bA = new Book("Java開發", 20.3);
        Book bB = new Book("Java開發", 20.3);
        System.out.println(bA.equals(bB)); // true
        System.out.println(bA.equals("Hello")); // false
    }
}

覆寫後的equals()用於進行對象比較。

Object接收引用類型

1、Object類是所有類的父類,因此Object類對象可以接收所有類型的對象,包括數組和接口對象。
範例:接收數組數據

public class Demo {
    public static void main(String[] args) {
        Object obj = new int[]{1, 2, 3};
        System.out.println(obj); // [I@1540e19d表示數組
        if (obj instanceof int[]) { // 如果是數組,則輸出
            int data[] = (int[]) obj; // 向下轉型
            for (int x = 0; x < data.length; x++) {
                System.out.println(data[x]);
            }
        }
    }
}

範例:接收接口對象

interface A {
    public void fun();
}

class B implements A {
    public void fun() {
        System.out.println("Hello");
    }
}

public class Demo {
    public static void main(String[] args) {
        A a = new B();
        Object obj = a;
        A t = (A) obj;
        t.fun(); // Hello
    }
}

上述代碼把參數類型統一爲Object,有利於開發。

Object修改鏈表

此時我們可以利用Object類的特點解決之前開發的鏈表存在的問題:由於參數類型不統一,每次使用都要進行重新開發
範例:修改鏈表

class Link { // 鏈表類,外部可見
    private class Node { // 節點類
        private Object data; // 保存數據
        private Node next; // 引用關係

        public Node(Object data) { // 有數據纔有Node
            this.data = data;
        }

        // 設置關係
        public void addNode(Node newNode) {
            if (this.next == null) {
                this.next = newNode;
            } else {
                this.next.addNode(newNode);
            }
        }

        // 數據查詢
        public boolean containsNode(Object data) {
            if (data.equals(this.data)) { // 當前數據等於要目標數據
                return true; // 結束查詢
            } else { // 當前數據不等於目標數據
                if (this.next != null) { // 有後續節點
                    return this.next.containsNode(data);
                } else { // 沒有後續節點
                    return false;
                }
            }
        }


        public Object getNode(int index) {
            // 當前foot內容與要查詢的索引比較
            // foot自增,目的是下次查詢方便
            if (Link.this.foot++ == index) {
                return this.data;
            } else {
                return this.next.getNode(index);
            }
        }

        // 修改節點信息
        public void setNode(int index, Object data) {
            if (Link.this.foot++ == index) {
                this.data = data;
            } else {
                this.next.setNode(index, data);
            }
        }

        // 刪除非根節點
        public void removeNode(Node previous, Object data) {
            // 參數中傳遞上一個節點和要刪除的數據
            if (data.equals(this.data)) {
                previous.next = this.next;
            } else {
                this.next.removeNode(this, data);
            }
        }


        public void toArrayNode() {
            Link.this.retArray[Link.this.foot++] = this.data;
            if (this.next != null) {
                this.next.toArrayNode();
            }
        }
    }


    // ====================以上爲內部類=====================
    private Node root; // 根節點
    private int count = 0; // 節點的個數
    private int foot = 0; // 索引
    private Object[] retArray; // 返回的數組

    public void add(Object data) {
        if (data == null) { // 輸入數據爲空
            return;
        }
        Node newNode = new Node(data); // 要保存的數據
        if (this.root == null) { // 根節點不存在
            this.root = newNode; // 設爲根節點
        } else { //  根節點存在,交由Node處理
            this.root.addNode(newNode);
        }
        this.count++; // 每次增加節點,count+1
    }


    // 獲取鏈表長度
    public int size() {
        return this.count;
    }

    // 判斷是否爲空鏈表
    public boolean isEmpty() {
        return this.count == 0;
    }


    // 判斷數據是否存在
    public boolean contains(Object data) {
        if (data == null || root == null) {
            return false;
        }
        return this.root.containsNode(data);
    }

    // 根據索引獲取信息
    public Object get(int index) {
        if (index > this.count) { // 超出查詢範圍
            return null;
        }
        this.foot = 0;
        return this.root.getNode(index); // 查詢交給Node類
    }


    // 設置信息
    public void set(int index, Object data) {
        if (index > this.count) {
            return;
        }
        this.foot = 0; // 重置foot,作爲索引
        this.root.setNode(index, data); // Node進行修改數據
    }

    // 判斷刪除節點是否爲root
    public void remove(Object data) {
        if (this.contains(data)) { // 判斷數據是否存在
            if (data.equals(this.root.data)) { // 判斷數據是否是root數據
                this.root = this.root.next;
            } else {
                // root是Node對象,此處直接訪問內部類私有操作
                this.root.next.removeNode(this.root, data);
            }
            this.count--; // 刪除後數據個數減少
        }
    }

    public Object[] toArray() {
        if (this.root == null) {
            return null;
        }
        this.foot = 0; // 需要腳標控制
        this.retArray = new Object[this.count]; // 根據保存內容開闢數組
        this.root.toArrayNode();
        return this.retArray;
    }
}

範例: 測試程序

public class Demo {
    public static void main(String[] args) {
        Link all = new Link();
        all.add("A");
        all.add("B");
        all.add("C");
        System.out.println(all.size());
        all.remove("B");
        Object[] data = all.toArray();
        for (int x = 0; x < data.length; x++) {
            String str = (String) data[x];
            System.out.println(str);
        }
    }
}

綜合實戰: 寵物商店

要求: 以程序結構爲主,實現一個寵物商店的模型,具有保存多個寵物的信息(名字,年齡),寵物上架、下架、模糊查詢功能。
思路圖
在這裏插入圖片描述

寵物商店的商品(寵物)要符合寵物這一標準(接口),寵物商店藉助鏈表實現上架、下架和模糊查詢功能。
範例:定義寵物的標準

interface Pet { // 定義寵物的標準
    public String getName();

    public int getAge();
}

寵物商店與具體的寵物無關,只和寵物這一接口有聯繫。
範例:定義寵物商店

class PetShop {
    private Link pets = new Link(); // 要保存的寵物信息

    public void add(Pet pet) { // 上架
        this.pets.add(pet);
    }

    public void delete(Pet pet) { // 下架
        this.pets.remove(pet);
    }

    public Link search(String keyWord) { // 模糊查詢,返回的內容個數不明
        Link result = new Link();
        // 將集合以數組的形式返回,
        // 真正要查詢的數據是Pet接口對象的getName()的返回值
        Object obj[] = this.pets.toArray();
        for (int x = 0; x < obj.length; x++) {
            Pet p = (Pet) obj[x];
            if (p.getName().contains(keyWord)) {
                result.add(p);
            }
        }
        return result;
    }
}

範例: 定義貓類

class Cat implements Pet {
    private String name;
    private int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }


    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }

        if (!(obj instanceof Cat)) {
            return false;
        }
        Cat cat = (Cat) obj;
        if (this.name.equals(cat.name)
                && this.age == cat.age) {
            return true;
        }
        return false;
    }

    public String toString() {
        return "貓名:" + this.name + ", 年齡" + this.age;
    }
}

可參照上述結構,定義一個狗類。
範例:測試

public class Demo {
    public static void main(String[] args) {
        PetShop shop = new PetShop();
        shop.add(new Cat("阿貓", 9));
        shop.add(new Cat("貓咪", 19));
        shop.add(new Dog("阿狗", 10));
        shop.add(new Dog("狗子", 8));
        // 模糊查詢
        Link all = shop.search("阿");
        Object obj[] = all.toArray();
        for (int x = 0; x < obj.length; x++) {
            System.out.println(obj[x]);
        }
        shop.delete(new Dog("狗子", 8));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章