2015年7月31日 星期五

Java上課練習:Object類別與集合

12_Object類別與集合

根據練習10_抽象類別 與 介面 完成code



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
interface 有攻擊能力的 {
    void attack(); // 自動補上 public abstract
}

 interface 會飛的 {
    void fly();  // 自動補上 public abstract
}


abstract public class Animal implements 有攻擊能力的 { // 抽象類別
    private String name; //封裝,隱藏資訊>setter&getter
    abstract public void attack(); // 抽象方法

//setter&getter
    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }
    
    public void print(){
        System.out.println("我的類別是" + this.getClass().getName() + ",名字叫" + name);
    }
    
}


class Dog extends Animal {
    @Override
    public void attack() { // 實作
        System.out.println("用牙齒咬");
    }
}

class Cat extends Animal {
    @Override
    public void attack() { // 實作
        System.out.println("用貓爪");
    }
}

// Bird 繼承 Animal 實作 會飛的 介面
class Bird extends Animal implements 會飛的 {
    @Override
    public void attack() { // 實作
        System.out.println("用頭撞");
    }
    @Override
    public void fly() {
        System.out.println("飛起來");
    }
}

// Airplane 自動繼承 Object 實作 會飛的 介面
class Airplane implements 會飛的 {
    @Override
    public void fly() {
        System.out.println("飛機起飛");
    }
}

class Superman implements 有攻擊能力的, 會飛的 {
    @Override
    public void attack() {
        System.out.println("超人 雷射攻擊");
    }
    @Override 
    public void fly() {
        System.out.println("超人 超音速飛行");
    }
}

其中 print()是繼承Object,取得該類別的名稱 getClass().getName()
public void print(){
        System.out.println("我的類別是" + this.getClass().getName() + ",名字叫" + name);
    }

新增一個AnimailTest主程式執行
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class AnimalTest {

    public static void main(String[] args) {
        Animal a;
        a = new Dog();
        a.setName("小白");
        a.print();
        a.attack();
    }
}

顯示結果

AnimailTest主程式中加入Object 類別 toString()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class AnimalTest {

    public static void main(String[] args) {
        Animal a;
        a = new Dog();
        a.setName("小白");
        a.print();
        a.attack();
        
        System.out.println("");
        System.out.println(a.getName()+"字串長度="+a.getName().length());
        
        System.out.println("");
        System.out.println(a.toString());//toString()從 Object 繼承
        System.out.println(a);//效果同上
        
        System.out.println("");
        System.out.println("基本資料="+a.toString());
        System.out.println("基本資料="+a);
               
    }

}

顯示結果


顯示結果中顯示的 Dog@19a32e0 為雜訊碼(hashcode),若要顯示正常字串,要在 Animal 類別中覆寫 toString( )

    @Override
    public String toString() {
        return "Animal{" + "name=" + name + '}';
    }

顯示結果

*************************************************************************************
物件的相等性
AnimailTest主程式中加入新的 Animal b=new Dog()
        //物件相等性
        System.out.println("");
        Animal b=new Dog();
        b.setName("小白");
        b.print();
        a.print();
        System.out.println("a==b is "+(a==b)); //兩個是否參考相同物件,是否共用同一個物件
        /*
        a新增一個物件Dog,b也新增一個物件Dog,所以a和b不是共用一個物件
        */
        System.out.println("a.equals(b) is "+a.equals(b)); //兩個物件,是否相等(比對欄位值)
        /*
        equals是比對Object內欄位是否 a==b,若沒有Override,則兩者沒有差異
        所以要覆寫Object的equals,至於要比對那些欄位才算兩個Object相等,由設計者決定
        例如,兩個員工是否相等,比對員工編號即可,不須比對電話、地址等欄位
        以此為例,在Animal中Override equals後,則a.equals(b)會判斷名字是否相同,若相同即回傳true
        若將b改為Cat,則a.equals(b),雖然名字一樣,但類別不一樣,所以回傳false
        */

== 兩個是否參考相同物件,是否共用同一個物件
equals 兩個物件,是否相等(比對欄位值)

equals是比對Object內欄位是否 a==b,若沒有Override,則兩者沒有差異
所以要覆寫Object的equals,至於要比對那些欄位才算兩個Object相等,由設計者決定
例如,兩個員工是否相等,比對員工編號即可,不須比對電話、地址等欄位
以此為例,在Animal中Override equals後,則a.equals(b)會判斷名字是否相同,若相同即回傳true
若將b改為Cat,則a.equals(b),雖然名字一樣,但類別不一樣,所以回傳false

Animal 類別中覆寫 equals( )
//通常覆寫equals會一併覆寫hashCode(雜訊碼)
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 23 * hash + Objects.hashCode(this.name);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        //a的equals和b比對,obj=b
        if (obj == null) { //判斷obj是否有物件
            return false;
        }
        if (getClass() != obj.getClass()) { //判斷a物件類別和b的物件類別是否相同,以此例要判斷是否為Dog類別(a)
            return false;
        }
        final Animal other = (Animal) obj; //將obj轉換同a的物件(Animal)
        if (!Objects.equals(this.name, other.name)) { //判斷a的物件名字和b的物件名字是否相同
            return false;
        }
        return true;
    }
通常覆寫equals()會一併覆寫hashCode()(雜訊碼)

在執行AnimailTest主程式會顯示以下結果

code
Animal
AnimalTest

沒有留言:

張貼留言