根據練習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(); } } |
顯示結果
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; }
在執行AnimailTest主程式會顯示以下結果
code
Animal
AnimalTest
沒有留言:
張貼留言