一、實(shí)驗(yàn)預(yù)熱
1、請(qǐng)敘述接口與抽象類的相同點(diǎn)和不同點(diǎn)。
1)關(guān)鍵字
interface
abstract
2)組成
抽象方法、全局常量
構(gòu)造方法、普通方法、抽象方法、static方法、常量、變量
3)子類使用
implements 接口
extends 抽象類
4)關(guān)系
不能繼承抽象類
可以實(shí)現(xiàn)多個(gè)接口
5)權(quán)限
只能使用public權(quán)限
可以使用各種權(quán)限
6)限制
沒有單繼承局限
單繼承局限
7)子類
子類必須要覆寫全部的抽象方法
8)實(shí)例化對(duì)象
依靠子類向上轉(zhuǎn)型
2、請(qǐng)舉出并描述生活中一些可以用接口定義標(biāo)準(zhǔn)的例子。
人和豬都會(huì)吃飯,但人要工作,豬不需要工作,可以定義一個(gè)吃飯的接口。
二、實(shí)驗(yàn)內(nèi)容
1、工廠模式
如果想要確認(rèn)一個(gè)代碼是否真的好,有這么幾個(gè)標(biāo)準(zhǔn):
1)客戶端調(diào)用簡(jiǎn)單,不需要關(guān)注具體的細(xì)節(jié)
2)客戶端之外的代碼修改,不影響用戶的使用,即用戶可以不用去關(guān)心代碼是否變更
請(qǐng)閱讀以下代碼:
interface Fruit {
public void eat();
}
class Apple implements Fruit {
public void eat() {
System.out.println("吃蘋果");
}
}
class Orange implements Fruit {
public void eat() {
System.out.println("吃橘子");
}
}
public class Test {
public static void main(String[] args) {
Fruit f = new Apple();
// Fruit f = new Orange();
f.eat();
}
}
請(qǐng)?jiān)谝陨洗a的基礎(chǔ)上進(jìn)行修改,增添Factory類,此類只包含一個(gè)靜態(tài)方法,用來(lái)通過判斷輸入的字符串來(lái)實(shí)例化不同水果類型的實(shí)例。
代碼:
package leif.tests;
public class ExperimentalReport {
public static void main(String[] args) {
Factory.getInstance("").eat();
Factory.getInstance("Apple").eat();
Factory.getInstance("Orange").eat();
}
}
interface Fruit {
public void eat();
}
class Apple implements Fruit {
@Override
public void eat() {
System.out.println("吃蘋果");
}
}
class Orange implements Fruit {
@Override
public void eat() {
System.out.println("吃橘子");
}
}
class Factory {
private Factory() {
};
public static Fruit getInstance(String fruit) {
switch (fruit) {
case "Apple":
return new Apple();
case "Orange":
return new Orange();
}
return new Fruit() {
@Override
public void eat() {
System.out.println("吃水果");
}
};
}
}
結(jié)果截圖:

2、代理模式
1)簡(jiǎn)單描述什么是代理模式
為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。在某些情況下,一個(gè)對(duì)象不適合或者不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介的作用。
2)代理模式的好處是什么
那先要說一下代理模式中的三種角色了。
抽象角色:聲明真實(shí)對(duì)象和代理對(duì)象的共同接口。
代理角色:代理對(duì)象內(nèi)部含有對(duì)真實(shí)對(duì)象的引用,從而可以操作真實(shí)對(duì)象,同時(shí)代理對(duì)象提供與真實(shí)對(duì)象相同的接口以便在任何時(shí)刻都能代替真實(shí)對(duì)象,同時(shí)代理對(duì)象可以在執(zhí)行真實(shí)對(duì)象操作時(shí),附加其他的操作,相當(dāng)于對(duì)真實(shí)對(duì)象進(jìn)行封裝。
真實(shí)角色:代理對(duì)象所代表的真實(shí)對(duì)象,是最終要引用的對(duì)象。
代理模式的一個(gè)好處就是對(duì)外部提供統(tǒng)一的接口方法,而代理類在接口中實(shí)現(xiàn)對(duì)真實(shí)類的附加操作行為,從而可以在不影響外部調(diào)用情況下,進(jìn)行系統(tǒng)擴(kuò)展。
例如:接口A有一個(gè)接口方法operator(),RealA實(shí)現(xiàn)接口A,則必須實(shí)現(xiàn)接口方法operator(),現(xiàn)在新需求需要修改RealA中的operator(),如果修改RealA就會(huì)影響原有系統(tǒng)的穩(wěn)定性,還要重新測(cè)試,這時(shí)就需要代理類實(shí)現(xiàn)附加行為操作。創(chuàng)建代理ProxyA實(shí)現(xiàn)接口A,并將真實(shí)對(duì)象RealA注入進(jìn)來(lái),ProxyA實(shí)現(xiàn)接口方法operator(),另外還可以增加附加行為,然后調(diào)用真實(shí)對(duì)象的operator(),從而保證了系統(tǒng)的穩(wěn)定性。
3)何種情況下使用代理模式
當(dāng)我們需要使用的對(duì)象很復(fù)雜或者需要很長(zhǎng)時(shí)間去構(gòu)造,這時(shí)就可以使用代理模式(Proxy)。例如如果構(gòu)建一個(gè)對(duì)象很耗費(fèi)時(shí)間和計(jì)算機(jī)資源,代理模式(Proxy)允許我們控制這種情況,直到我們需要使用實(shí)際的對(duì)象。一個(gè)代理(Proxy)通常包含和將要使用的對(duì)象同樣的方法,一旦開始使用這個(gè)對(duì)象,這些方法將通過代理(Proxy)傳遞給實(shí)際的對(duì)象。
4)一個(gè)代理模式的簡(jiǎn)單例子:
A1想吃飯,于是讓B帶飯,正好A2也想吃飯,所以B也要順便給A2帶飯,寫出代碼和輸出。
代碼:
package leif.tests;
public class ExperimentalReport {
public static void main(String[] args) {
BringFood bringFood = new B();
((B)bringFood).setBringFood(new A1());
bringFood.findSomeone();
((B)bringFood).setBringFood(new A2());
bringFood.findSomeone();
}
}
interface BringFood {
public abstract void findSomeone();
}
class A1 implements BringFood {
@Override
public void findSomeone() {
System.out.println("A1找人帶飯");
}
}
class A2 implements BringFood {
@Override
public void findSomeone() {
System.out.println("A2找人帶飯");
}
}
class B implements BringFood {
private BringFood bringFood;
public BringFood getBringFood() {
return bringFood;
}
public void setBringFood(BringFood bringFood) {
this.bringFood = bringFood;
}
@Override
public void findSomeone() {
bringFood.findSomeone();
}
}
結(jié)果截圖:
