
Object類是類層次結構的根類,每個類都使用Object作為超類(父類).
指示其他某個對象是否與此對象“相等”.
示例代碼;
(相關資料圖)
/*** 學生類*/public class Student extends Object{ String stuNo; String stuName; int age; public void show() { System.out.println("學號:"+stuNo+" 姓名:"+stuName+" 年齡:"+age); } @Override public boolean equals(Object obj) { if(obj==null) { return false; } //強制類型轉換 //注意:可能的NullPointerException Student stu=(Student)obj; //比較學號和姓名if(this.stuNo.equals(stu.stuNo)&&this.name.equals(stu.name)){ return true; } return false; } }public class Test { public static void main(String[] args) { Student zhangsan=new Student(); zhangsan.stuNo="bj1805"; zhangsan.stuName="xxx"; zhangsan.age=20; Student lisi=new Student(); lisi.stuNo="bj1805"; lisi.stuName="xxx"; lisi.age=20; boolean b=zhangsan.equals(lisi); boolean b2=zhangsan==lisi; System.out.println(b); System.out.println(b2); }}
1. ==: 如果是基本類型進行比較,則比較的是數值; 如果是引用類型進行比較,則比較的是對象的引用(地址); 2. 默認情況下,Object中的 equals和 == 一樣;3. String類型中重寫了Object中的equals方法,所以String中的比較使用equals()方法.
返回該對象的哈希碼值(理解為對象的地址),每一個對象的哈希碼值唯一.
示例:
Object obj1 = new Object();Object obj2 = new Object();Object obj3 = obj2; //obj2與obj3兩個對象的哈希碼值一樣System.out.println(obj1.hashCode()); System.out.println(obj2.hashCode()); System.out.println(obj3.hashCode());
返回此Object的運行時類,獲取某個類的類對象.
示例:
Object obj = new Object();Class cls = obj.getClass();//通過反射獲取到了Object類
返回該對象的字符串,可以在自定義類中重寫toString方法,以實現是對象轉成指定格式的字符串.
示例
public class Person{ String name; public Person(String name){ this.name = name; } //重寫toString方法 public String toString(){ return "name="+name; }}public class DemoPerson{ public static void main(String[]args){ Person p = new Person("張三"); System.out.println(p);//輸出結果為:name=張三 }}
在生活中,一類事物有多種表現形態,對象的多種形態. 比如: 某個音樂家有三個兒子: 大兒子會唱美聲,二兒子會唱流行,三兒子唱搖滾.程序中舉例, 動物是父類: Dog會旺旺,Cat會喵喵,Pig會哼哼.程序中的 多態: 同一個父類引用類型,使用不同的子類實例可以執行不同的操作.
需求:
編寫一個寵物類 Pet, 屬性: id,name,health,love;方法有print(),打印信息,要封裝成員變量.兩個子類狗狗和貓類,狗狗有品種(strain),貓類有愛好(hobby),重寫父類print()方法;寵物餓了,需要主人給寵物喂食,狗狗吃狗糧、貓咪吃小魚,吃完之后健康值狗狗增加3斤,貓咪增加5斤.示例:
/*寵物類*/package com.syc.day08;public class Pet{ private int id; //id 寵物編號 private String name;// 寵物昵稱 private int health;// 健康值 private int love;// 親密度 public void setId(int id){ this.id=id; } public int getId(){ return id; } public void setName(String name){ this.name=name; } public String getName(){ return name; } public void setHealth(int health){ this.health=health; } public int getHealth(){ return health; } public void setLove(int love){ this.love=love; } public int getLove(){ return love; } //方法 public void print(){ System.out.println("寵物id:"+this.id+",寵物昵稱:"+this.name+",健康值:"+health+", 親密度:"+love); } }/*dog類繼承Pet類*/package com.syc.day08;public class Dog extends Pet{ private String strain; public void setStrain(String strain){ this.strain=strain; } public String getStrain(){ return strain; } public void print(){ int id=getId(); String name=getName(); int health=getHealth(); int love=getLove(); System.out.println("狗狗id:"+id+" 昵稱:"+name+" 健康值:"+health+" 親密度:"+love+" 品種:"+strain); } public void eat(){ String name=getName(); System.out.println(name+"大口吃狗糧...."); //增加健康值 int health=getHealth(); setHealth(health+3); } }/*貓類*/package com.syc.day08;public class Cat extends Pet{ private String hobby; public void setHobby(String hobby){ this.hobby=hobby; } public String getHobby(){ return hobby; } public void print(){ int id=getId(); String name=getName(); int health=getHealth(); int love=getLove(); System.out.println("貓咪id:"+id+" 昵稱:"+name+" 健康值:"+health+" 親密度:"+love+" 愛好:"+hobby); } public void eat(){ String name=getName(); System.out.println(name+"大口吃小魚...."); //增加健康值 int health=getHealth(); setHealth(health+5); }}/*主人*/package com.syc.day08;public class Master{ private String name; public void setName(String name){ this.name=name; } public String getName(){ return name; } //喂食 public void feed(Dog d){ System.out.println(name+"要給狗狗喂食物..."); d.eat(); d.print(); } public void feed(Cat c){ System.out.println(name+"要給貓咪喂食物..."); c.eat(); c.print(); }}package com.syc.day08;public class TestPet{ public static void main(String[] args){ Dog afu=new Dog(); afu.setId(120); afu.setName("阿福"); afu.setHealth(85); afu.setLove(90); afu.setStrain("拉布拉多"); afu.print(); Cat amao=new Cat(); amao.setId(119); amao.setName("阿貓"); amao.setHealth(90); amao.setLove(70); amao.setHobby("爬樹"); amao.print(); Master yuhuan=new Master(); yuhuan.setName("小美"); yuhuan.feed(afu); yuhuan.feed(amao); }}
思考:
如果再領養XXX寵物,就需要給XXX喂食,怎么辦? 這樣頻繁修改代碼,代碼可擴展性、可維護性差,考慮使用多態來優化代碼.
示例:
/*public void feed(Dog d){ System.out.println(name+"要給狗狗喂食物..."); d.eat(); d.print();}public void feed(Cat c){ System.out.println(name+"要給貓咪喂食物..."); c.eat(); c.print();}*/public void feed(Pet p){ String n=p.getName(); System.out.println(name+"要給"+n+"喂食物..."); p.eat();//調用子類重寫的方法 p.print();//調用子類重寫的方法}
上機練習:
使用多態實現領養寵物,使用父類作為方法返回值.
//主人類中添加領養方法 //領養 public Pet adopt(int type){ if(type==1){ Pet d=new Dog(); d.setHealth(80); d.setLove(50); return d; }else if(type==2){ Pet c=new Cat(); c.setHealth(80); c.setLove(50); return c; }else{ return null; } } /*領養寵物*/package com.syc.day08;import java.util.Scanner;public class TestPet2{ public static void main(String[] args){ System.out.println("歡迎來到xxx寵物商店....."); System.out.println("請選擇您要領養的寵物類型. 1 狗狗; 2 貓咪"); Scanner input=new Scanner(System.in); int choice=input.nextInt(); Master yuhuan=new Master(); Pet p=yuhuan.adopt(choice); if(p!=null){ System.out.println("領養成功"); p.print(); }else{ System.out.println("領養失敗"); } } }
向上轉型:
將子類的對象賦值給父類變量,自動轉換.
Pet pet1 = new Dog();Pet pet2 = new Cat();String str = "abc";Object obj = str;
注意:
<父類型> <引用變量名> = new <子類型>();此時通過父類引用變量調用的方法是子類重寫或父類的方法, 編譯時看父類,運行時看子類;此時通過父類引用變量無法調用子類特有的屬性和方法.向下轉型:
將父類的變量賦值給子類變量,強制轉換.
Object obj = new String("abc");String str = (String)obj;Pet pet=new Dog(); // Pet pet=new Cat(); Dog d=(Dog)pet; //向下轉型
注意:
<子類型> <引用變量名> = (<子類型> )<父類型的引用變量>;在向下轉型的過程中,如果沒有轉換為真實子類類型,會出現類型轉換異常ClassCastException.上機練習: 實現主人與寵物玩耍功能
//貓咪捉迷藏: 貓類中public void hideAndSeek(){ String name=getName(); System.out.println(name+"玩捉迷藏..."); int health=getHealth(); setHealth(health-5);}//接球: 狗狗類public void catchBall(){ String name=getName(); System.out.print(name+"玩接球游戲...."); int health=getHealth(); setHealth(health-3);}//和寵物玩耍public void play(Pet pet){ if(pet instanceof Dog){ Dog d=(Dog)pet; d.catchBall(); }else if(pet instanceof Cat){ Cat c=(Cat)pet; c.hideAndSeek(); }}
對象向下轉型時,存在一個問題: 若一個父類A的引用a,指向一個子類B的實例,將a賦值給另一個子類C引用時,會拋出java.lang.ClassCastException異常.
拋出異常后,程序將不能繼續向下執行.為了避免這個異常的拋出,我們可以通過instanceof關鍵字,來判斷引用指向的實例是否可以進行強制轉換成某個子類對象.
示例:
已知Pet類有兩個子類Dog和Cat:
public class Demo{ public static void main(String[]args){ Pet a = new Dog(); check(a); } //設計一個方法,判斷一個動物是貓還是狗 public static void check(Pet a){ if(a instanceof Dog){ System.out.println("狗"); }else if(a instanceof Cat){ System.out.println("貓"); } }}
final: 最終的.可以使用final關鍵字來修飾Java的類、屬性和方法.
final修飾成員變量或局部變量,則成為(符號)常量,只能賦值一次,用大寫字母表示.
修飾成員變量時,定義時同時給出初始值,或在構造方法中賦值;修飾局部變量時,只能賦值一次.則該方法不能被子類重寫,但能被繼承.
final returnType methodName(paramList){ ... }
final class finalClassName{ ... }
1. Object類: 所有類的父類,默認繼承Object.2. equals()方法: 判斷兩個對象是否相等, this==obj; ==: 基本類型比較數據,引用類型比較地址/ equals() 默認 和 == 一樣; hashCode()方法: 返回對象的地址; getClass()方法: 返回類對象; toString()方法: 返回對象的字符串形式.3. 多態: 同一個父類引用類型,使用不同的子類實例,執行不同的操作. 父類引用子類對象實現多態的要素或條件: ①. 子類繼承父類,子類必須重寫父類的方法; ②. 使用父類變量,子類對象. 多態表現形式: ①. 使用父類作為方法的參數; ②. 使用父類作為方法的返回值.4. 向上轉型和向下轉型 向上轉型: 子類轉成父類; 向下轉型: 父類轉成子類,先向上轉型,才能向下轉型. 5. instanceof: 判斷對象是否是某種類型. if(pet instanceof Dog){ Dog dog=(Dog)pet; } 6. final 終止的. ①. final修飾變量,常量:只能賦值一次; ②. 修飾成員變量; ③. 修飾局部變量. ④. final修飾方法,該方法屬于終止方法,不能被重寫, 但能被繼承. ⑤. final修飾類,終止類,不能被繼承.