長沙網(wǎng)站開發(fā)微聯(lián)百度搜索什么關(guān)鍵詞能搜到網(wǎng)站
1.接口
1.1黑馬信息管理系統(tǒng)集合改進 (應(yīng)用)
-
使用數(shù)組容器的弊端
-
容器長度是固定的,不能根據(jù)添加功能自動增長
-
沒有提供用于贈刪改查的方法
-
-
優(yōu)化步驟
-
創(chuàng)建新的StudentDao類,OtherStudentDao
-
創(chuàng)建ArrayList集合容器對象
-
OtherStudentDao中的方法聲明,需要跟StudentDao保持一致
注意:如果不一致,StudentService中的代碼就需要進行修改
-
完善方法(添加、刪除、修改、查看)
-
替換StudentService中的Dao對象
-
-
代碼實現(xiàn)
OtherStudentDao類
public class OtherStudentDao {// 集合容器private static ArrayList<Student> stus = new ArrayList<>(); ?static {Student stu1 = new Student("heima001","張三","23","1999-11-11");Student stu2 = new Student("heima002","李四","24","2000-11-11"); ?stus.add(stu1);stus.add(stu2);} ?// 添加學(xué)生方法public boolean addStudent(Student stu) {stus.add(stu);return true;} ?// 查看學(xué)生方法public Student[] findAllStudent() { ?Student[] students = new Student[stus.size()]; ?for (int i = 0; i < students.length; i++) {students[i] = stus.get(i);} ?return students;} ?public void deleteStudentById(String delId) {// 1. 查找id在容器中所在的索引位置int index = getIndex(delId);stus.remove(index);} ?public int getIndex(String id){int index = -1;for (int i = 0; i < stus.size(); i++) {Student stu = stus.get(i);if(stu != null && stu.getId().equals(id)){index = i;break;}}return index;} ?public void updateStudent(String updateId, Student newStu) {// 1. 查找updateId, 在容器中的索引位置int index = getIndex(updateId);stus.set(index, newStu);} }
StudentService類
public class StudentService {// 創(chuàng)建StudentDao (庫管)private OtherStudentDao studentDao = new OtherStudentDao();// 其他方法沒有變化,此處省略... } ? ?
1.2黑馬信息管理系統(tǒng)抽取Dao (應(yīng)用)
-
優(yōu)化步驟
-
將方法向上抽取,抽取出一個父類 ( BaseStudentDao )
-
方法的功能實現(xiàn)在父類中無法給出具體明確,定義為抽象方法
-
讓兩個類分別繼承 BaseStudentDao ,重寫內(nèi)部抽象方法
-
-
代碼實現(xiàn)
BaseStudentDao類
public abstract class BaseStudentDao {// 添加學(xué)生方法public abstract boolean addStudent(Student stu);// 查看學(xué)生方法public abstract Student[] findAllStudent();// 刪除學(xué)生方法public abstract void deleteStudentById(String delId);// 根據(jù)id找索引方法public abstract int getIndex(String id);// 修改學(xué)生方法public abstract void updateStudent(String updateId, Student newStu); }
StudentDao類
public class StudentDao extends BaseStudentDao {// 其他內(nèi)容不變,此處省略 }
OtherStudentDao類
public class OtherStudentDao extends BaseStudentDao {// 其他內(nèi)容不變,此處省略 }
1.3接口的概述(理解)
-
接口就是一種公共的規(guī)范標(biāo)準(zhǔn),只要符合規(guī)范標(biāo)準(zhǔn),大家都可以通用。
-
Java中接口存在的兩個意義
-
用來定義規(guī)范
-
用來做功能的拓展
-
1.4接口的特點(記憶)
-
接口用關(guān)鍵字interface修飾
public interface 接口名 {}
-
類實現(xiàn)接口用implements表示
public class 類名 implements 接口名 {}
-
接口不能實例化
我們可以創(chuàng)建接口的實現(xiàn)類對象使用
-
接口的子類
要么重寫接口中的所有抽象方法
要么子類也是抽象類
1.5接口的成員特點(記憶)
-
成員特點
-
成員變量
只能是常量 ? 默認修飾符:public static final
-
構(gòu)造方法
沒有,因為接口主要是擴展功能的,而沒有具體存在
-
成員方法
只能是抽象方法
默認修飾符:public abstract
關(guān)于接口中的方法,JDK8和JDK9中有一些新特性,后面再講解
-
-
代碼演示
-
接口
public interface Inter {public static final int NUM = 10; ?public abstract void show(); }
-
實現(xiàn)類
class InterImpl implements Inter{ ?public void method(){// NUM = 20;System.out.println(NUM);} ?public void show(){ ?} }
-
測試類
public class TestInterface {/*成員變量: 只能是常量 系統(tǒng)會默認加入三個關(guān)鍵字public static final構(gòu)造方法: 沒有成員方法: 只能是抽象方法, 系統(tǒng)會默認加入兩個關(guān)鍵字public abstract*/public static void main(String[] args) {System.out.println(Inter.NUM);}}
-
1.6類和接口的關(guān)系(記憶)
-
類與類的關(guān)系
繼承關(guān)系,只能單繼承,但是可以多層繼承
-
類與接口的關(guān)系
實現(xiàn)關(guān)系,可以單實現(xiàn),也可以多實現(xiàn),還可以在繼承一個類的同時實現(xiàn)多個接口
-
接口與接口的關(guān)系
繼承關(guān)系,可以單繼承,也可以多繼承
1.7黑馬信息管理系統(tǒng)使用接口改進 (應(yīng)用)
-
實現(xiàn)步驟
-
將 BaseStudentDao 改進為一個接口
-
讓 StudentDao 和 OtherStudentDao 去實現(xiàn)這個接口
-
-
代碼實現(xiàn)
BaseStudentDao接口
public interface BaseStudentDao {// 添加學(xué)生方法public abstract boolean addStudent(Student stu);// 查看學(xué)生方法public abstract Student[] findAllStudent();// 刪除學(xué)生方法public abstract void deleteStudentById(String delId);// 根據(jù)id找索引方法public abstract int getIndex(String id);// 修改學(xué)生方法public abstract void updateStudent(String updateId, Student newStu); }
StudentDao類
public class StudentDao implements BaseStudentDao {// 其他內(nèi)容不變,此處省略 }
OtherStudentDao類
public class OtherStudentDao implements BaseStudentDao {// 其他內(nèi)容不變,此處省略 }
1.8黑馬信息管理系統(tǒng)解耦合改進 (應(yīng)用)
-
實現(xiàn)步驟
-
創(chuàng)建factory包,創(chuàng)建 StudentDaoFactory(工廠類)
-
提供 static 修改的 getStudentDao 方法,該方法用于創(chuàng)建StudentDao對象并返回
-
-
代碼實現(xiàn)
StudentDaoFactory類
public class StudentDaoFactory {public static OtherStudentDao getStudentDao(){return new OtherStudentDao();} }
StudentService類
public class StudentService {// 創(chuàng)建StudentDao (庫管)// private OtherStudentDao studentDao = new OtherStudentDao(); ?// 通過學(xué)生庫管工廠類, 獲取庫管對象private OtherStudentDao studentDao = StudentDaoFactory.getStudentDao(); } ?
2.接口組成更新
2.1接口組成更新概述【理解】
-
常量
public static final
-
抽象方法
public abstract
-
默認方法(Java 8)
-
靜態(tài)方法(Java 8)
-
私有方法(Java 9)
2.2接口中默認方法【應(yīng)用】
-
格式
public default 返回值類型 方法名(參數(shù)列表) { }
-
作用
解決接口升級的問題
-
范例
public default void show3() { }
注意事項
-
默認方法不是抽象方法,所以不強制被重寫。但是可以被重寫,重寫的時候去掉default關(guān)鍵字
-
public可以省略,default不能省略
-
如果實現(xiàn)了多個接口,多個接口中存在相同的方法聲明,子類就必須對該方法進行重寫
-
2.3接口中靜態(tài)方法【應(yīng)用】
-
格式
public static 返回值類型 方法名(參數(shù)列表) { }
范例
-
靜態(tài)方法只能通過接口名調(diào)用,不能通過實現(xiàn)類名或者對象名調(diào)用
-
public可以省略,static不能省略
-
-
public static void show() { }
注意事項
-
靜態(tài)方法只能通過接口名調(diào)用,不能通過實現(xiàn)類名或者對象名調(diào)用
-
public可以省略,static不能省略
2.4接口中私有方法【應(yīng)用】
-
私有方法產(chǎn)生原因
Java 9中新增了帶方法體的私有方法,這其實在Java 8中就埋下了伏筆:Java 8允許在接口中定義帶方法體的默認方法和靜態(tài)方法。這樣可能就會引發(fā)一個問題:當(dāng)兩個默認方法或者靜態(tài)方法中包含一段相同的代碼實現(xiàn)時,程序必然考慮將這段實現(xiàn)代碼抽取成一個共性方法,而這個共性方法是不需要讓別人使用的,因此用私有給隱藏起來,這就是Java 9增加私有方法的必然性
-
定義格式
-
格式1
private 返回值類型 方法名(參數(shù)列表) { }
-
范例1
private void show() { ? }
-
格式2
private static 返回值類型 方法名(參數(shù)列表) { }
-
范例2
private static void method() { ? }
-
-
注意事項
-
默認方法可以調(diào)用私有的靜態(tài)方法和非靜態(tài)方法
-
靜態(tài)方法只能調(diào)用私有的靜態(tài)方法
-
3.多態(tài)
3.1多態(tài)的概述(記憶)
-
什么是多態(tài)
同一個對象,在不同時刻表現(xiàn)出來的不同形態(tài)
-
多態(tài)的前提
-
要有繼承或?qū)崿F(xiàn)關(guān)系
-
要有方法的重寫
-
要有父類引用指向子類對象
-
-
代碼演示
class Animal {public void eat(){System.out.println("動物吃飯");} } ? class Cat extends Animal {@Overridepublic void eat() {System.out.println("貓吃魚");} } ? public class Test1Polymorphic {/*多態(tài)的前提: ?1. 要有(繼承 \ 實現(xiàn))關(guān)系2. 要有方法重寫3. 要有父類引用, 指向子類對象*/public static void main(String[] args) {// 當(dāng)前事物, 是一只貓Cat c = new Cat();// 當(dāng)前事物, 是一只動物Animal a = new Cat();a.eat(); ?} }
3.2多態(tài)中的成員訪問特點(記憶)
-
成員訪問特點
-
成員變量
編譯看父類,運行看父類
-
成員方法
編譯看父類,運行看子類
-
-
代碼演示
class Fu {int num = 10; ?public void method(){System.out.println("Fu.. method");} } ? class Zi extends Fu {int num = 20; ?public void method(){System.out.println("Zi.. method");} } ? public class Test2Polymorpic {/*多態(tài)的成員訪問特點: ?成員變量: 編譯看左邊 (父類), 運行看左邊 (父類) ?成員方法: 編譯看左邊 (父類), 運行看右邊 (子類)*/public static void main(String[] args) {Fu f = new Zi();System.out.println(f.num);f.method();} }
3.3多態(tài)的好處和弊端(記憶)
-
好處
提高程序的擴展性。定義方法時候,使用父類型作為參數(shù),在使用的時候,使用具體的子類型參與操作
-
弊端
不能使用子類的特有成員
3.4多態(tài)中的轉(zhuǎn)型(應(yīng)用)
-
向上轉(zhuǎn)型
父類引用指向子類對象就是向上轉(zhuǎn)型
-
向下轉(zhuǎn)型
格式:子類型 對象名 = (子類型)父類引用;
-
代碼演示
class Fu {public void show(){System.out.println("Fu..show...");} } ? class Zi extends Fu {@Overridepublic void show() {System.out.println("Zi..show...");} ?public void method(){System.out.println("我是子類特有的方法, method");} } ? public class Test3Polymorpic {public static void main(String[] args) {// 1. 向上轉(zhuǎn)型 : 父類引用指向子類對象Fu f = new Zi();f.show();// 多態(tài)的弊端: 不能調(diào)用子類特有的成員// f.method(); ?// A: 直接創(chuàng)建子類對象// B: 向下轉(zhuǎn)型 ?// 2. 向下轉(zhuǎn)型 : 從父類類型, 轉(zhuǎn)換回子類類型Zi z = (Zi) f;z.method();} }
3.5多態(tài)中轉(zhuǎn)型存在的風(fēng)險和解決方案 (應(yīng)用)
-
風(fēng)險
如果被轉(zhuǎn)的引用類型變量,對應(yīng)的實際類型和目標(biāo)類型不是同一種類型,那么在轉(zhuǎn)換的時候就會出現(xiàn)ClassCastException
-
解決方案
-
關(guān)鍵字
instanceof
-
使用格式
變量名 instanceof 類型
通俗的理解:判斷關(guān)鍵字左邊的變量,是否是右邊的類型,返回boolean類型結(jié)果
-
-
代碼演示
abstract class Animal {public abstract void eat(); } ? class Dog extends Animal {public void eat() {System.out.println("狗吃肉");} ?public void watchHome(){System.out.println("看家");} } ? class Cat extends Animal {public void eat() {System.out.println("貓吃魚");} } ? public class Test4Polymorpic {public static void main(String[] args) {useAnimal(new Dog());useAnimal(new Cat());} ?public static void useAnimal(Animal a){ ?// Animal a = new Dog();// Animal a = new Cat();a.eat();//a.watchHome(); ? // ? ? ? Dog dog = (Dog) a; // ? ? ? dog.watchHome(); // ClassCastException 類型轉(zhuǎn)換異常// 判斷a變量記錄的類型, 是否是Dogif(a instanceof Dog){Dog dog = (Dog) a;dog.watchHome();}} ? }
3.6黑馬信息管理系統(tǒng)多態(tài)改進 (應(yīng)用)
-
實現(xiàn)步驟
-
StudentDaoFactory類中方法的返回值定義成父類類型BaseStudentDao
-
StudentService中接收方法返回值的類型定義成父類類型BaseStudentDao
-
-
代碼實現(xiàn)
StudentDaoFactory類
public class StudentDaoFactory {public static BaseStudentDao getStudentDao(){return new OtherStudentDao();} }
StudentService類
public class StudentService {// 創(chuàng)建StudentDao (庫管)// private OtherStudentDao studentDao = new OtherStudentDao(); ?// 通過學(xué)生庫管工廠類, 獲取庫管對象private BaseStudentDao studentDao = StudentDaoFactory.getStudentDao(); } ?