世界信息:6.面向?qū)ο缶幊?下)

2022-12-26 10:17:53 來源:51CTO博客

一、關(guān)鍵字:static

當我們編寫一個類時,其實就是在描述其對象的屬性和行為,而并沒有產(chǎn)生實質(zhì)上 的對象,只有通過new關(guān)鍵字才會產(chǎn)生出對象,這時系統(tǒng)才會分配內(nèi)存空間給對象, 其方法才可以供外部調(diào)用。我們有時候希望無論是否產(chǎn)生了對象或無論產(chǎn)生了多少 對象的情況下,某些特定的數(shù)據(jù)在內(nèi)存空間里只有一份,例如所有的中國人都有個 國家名稱,每一個中國人都共享這個國家名稱,不必在每一個中國人的實例對象中 都單獨分配一個用于代表國家名稱的變量。

如果想讓一個類的所有實例共享數(shù)據(jù),就用類變量!

1.類屬性、類方法的設(shè)計思想
類屬性作為該類各個對象之間共享的變量。在設(shè)計類時,分析哪些屬性不因?qū)ο蟮牟煌淖?,將這些屬性設(shè)置為類屬性。相應(yīng)的方法設(shè)置為類方法。如果方法與調(diào)用者無關(guān),則這樣的方法通常被聲明為類方法,由于不需要創(chuàng)建對象就可以調(diào)用類方法,從而簡化了方法的調(diào)用。使用范圍:在Java類中,可用static修飾屬性、方法、代碼塊、內(nèi)部類被修飾后的成員具備以下特點:隨著類的加載而加載優(yōu)先于對象存在修飾的成員,被所有對象所共享訪問權(quán)限允許時,可不創(chuàng)建對象,直接被類調(diào)用
2.類變量(class Variable)
類變量(類屬性)由該類的所有實例共享類變量應(yīng)用舉例
class Person {   private int id;  public static int total = 0;  public Person() {    total++;    id = total;  }public static void main(String args[]){  Person Tom=new Person();  Tom.id=0;  total=100; // 不用創(chuàng)建對象就可以訪問靜態(tài)成員  }}
public class StaticDemo {public static void main(String args[]) {  Person.total = 100; // 不用創(chuàng)建對象就可以訪問靜態(tài)成員  //訪問方式:類名.類屬性,類名.類方法  System.out.println(Person.total);  Person c = new Person();  System.out.println(c.total); //輸出101  } }
3.類變量 vs 實例變量內(nèi)存解析
4.類方法(class method)
沒有對象的實例時,可以用類名.方法名()的形式訪問由static修飾的類方法。在static方法內(nèi)部只能訪問類的static修飾的屬性或方法,不能訪問類的非static的結(jié)構(gòu)。因為不需要實例就可以訪問static方法,因此static方法內(nèi)部不能有this。(也 不能有super ? YES!)static修飾的方法不能被重寫
5.單例 (Singleton)設(shè)計模式
設(shè)計模式==是在大量的實踐中總結(jié)和理論化之后優(yōu)選的代碼結(jié)構(gòu)、編程風(fēng)格、 以及解決問題的思考方式。==設(shè)計模免去我們自己再思考和摸索。就像是經(jīng)典 的棋譜,不同的棋局,我們用不同的棋譜?!碧茁贰彼^類的單例設(shè)計模式,就是采取一定的方法保證在整個的軟件系統(tǒng)中,對某個類只能存在一個對象實例,并且該類只提供一個取得其對象實例的方法。 如果我們要讓類在一個虛擬機中只能產(chǎn)生一個對象,我們首先必須將類的構(gòu)造器的訪問權(quán)限設(shè)置為private,這樣,就不能用new操作符在類的外部產(chǎn)生 類的對象了,但在類內(nèi)部仍可以產(chǎn)生該類的對象。因為在類的外部開始還無 法得到類的對象,只能調(diào)用該類的某個靜態(tài)方法以返回類內(nèi)部創(chuàng)建的對象, 靜態(tài)方法只能訪問類中的靜態(tài)成員變量,所以,指向類內(nèi)部產(chǎn)生的該類對象的變量也必須定義成靜態(tài)的
單例(Singleton)設(shè)計模式-餓漢式
單例(Singleton)設(shè)計模式-懶漢式

懶漢式暫時還存在線 程安全問題,講到多 線程時,可修復(fù)


(相關(guān)資料圖)

單例模式的優(yōu)點:由于單例模式只生成一個實例,減少了系統(tǒng)性能開銷,當一個對象的 產(chǎn)生需要比較多的資源時,如讀取配置、產(chǎn)生其他依賴對象時,則可 以通過在應(yīng)用啟動時直接產(chǎn)生一個單例對象,然后永久駐留內(nèi)存的方 式來解決。舉例 java.lang.Runtime
public class Runtime {    private static Runtime currentRuntime = new Runtime();    /**     * Returns the runtime object associated with the current Java application.     * Most of the methods of class Runtime are instance     * methods and must be invoked with respect to the current runtime object.     *     * @return  the Runtime object associated with the current     *          Java application.     */    public static Runtime getRuntime() {        return currentRuntime;    }    /** Don"t let anyone else instantiate this class */    private Runtime() {}
網(wǎng)站的計數(shù)器,一般也是單例模式實現(xiàn),否則難以同步。應(yīng)用程序的日志應(yīng)用,一般都使用單例模式實現(xiàn),這一般是由于共享的日志文件一直處于打開狀態(tài),因為只能有一個實例去操作,否則內(nèi)容不好追加。數(shù)據(jù)庫連接池的設(shè)計一般也是采用單例模式,因為數(shù)據(jù)庫連接是一種數(shù)據(jù)庫資源。項目中,讀取配置文件的類,一般也只有一個對象。沒有必要每次使用配置 文件數(shù)據(jù),都生成一個對象去讀取。Application也是單例的典型應(yīng)用Windows的==Task Manager (任務(wù)管理器)==就是很典型的單例模式Windows的==Recycle Bin (回收站)==也是典型的單例應(yīng)用。在整個系統(tǒng)運行過程中,回收站一直維護著僅有的一個實例。

二、理解main方法的語法

由于Java虛擬機需要調(diào)用類的main()方法,所以該方法的訪問權(quán)限必須是 public,又因為Java虛擬機在執(zhí)行main()方法時不必創(chuàng)建對象,所以該方法必須 是static的,該方法接收一個String類型的數(shù)組參數(shù),該數(shù)組中保存執(zhí)行Java命令 時傳遞給所運行的類的參數(shù)。又因為main() 方法是靜態(tài)的,我們不能直接訪問該類中的非靜態(tài)成員,必須創(chuàng) 建該類的一個實例對象后,才能通過這個對象去訪問類中的非靜態(tài)成員,這種情 況,我們在之前的例子中多次碰到。
命令行參數(shù)用法舉例
public class CommandPara {  public static void main(String[] args) {    for (int i = 0; i < args.length; i++) {      System.out.println("args[" + i + "] = " + args[i]);    }  }}
//運行程序CommandPara.javajava CommandPara “Tom" “Jerry" “Shkstart"http://輸出結(jié)果:args[0] = Tomargs[1] = Jerryargs[2] = Shkstart

三、類的成員之四: 代碼塊

代碼塊(或初始化塊)的作用:對Java類或?qū)ο筮M行初始化代碼塊(或初始化塊)的分類:一個類中代碼塊若有修飾符,則只能被static修飾,稱為靜態(tài)代碼塊 (static block),沒有使用static修飾的,為非靜態(tài)代碼塊。static代碼塊通常用于初始化static的屬性
class Person {  public static int total;  static {    total = 100;//為total賦初值  }  …… //其它屬性或方法聲明}
靜態(tài)代碼塊:用static 修飾的代碼塊可以有輸出語句。可以對類的屬性、類的聲明進行初始化操作。不可以對非靜態(tài)的屬性初始化。即:不可以調(diào)用非靜態(tài)的屬性和方法。若有多個靜態(tài)的代碼塊,那么按照從上到下的順序依次執(zhí)行。靜態(tài)代碼塊的執(zhí)行要先于非靜態(tài)代碼塊。靜態(tài)代碼塊隨著類的加載而加載,且只執(zhí)行一次。非靜態(tài)代碼塊:沒有static修飾的代碼塊可以有輸出語句。可以對類的屬性、類的聲明進行初始化操作。除了調(diào)用非靜態(tài)的結(jié)構(gòu)外,還可以調(diào)用靜態(tài)的變量或方法。若有多個非靜態(tài)的代碼塊,那么按照從上到下的順序依次執(zhí)行。每次創(chuàng)建對象的時候,都會執(zhí)行一次。且先于構(gòu)造器執(zhí)行。
靜態(tài)初始化塊舉例
class Person {  public static int total;  static {    total = 100;    System.out.println("in static block!");  }}
public class PersonTest {  public static void main(String[] args) {    System.out.println("total = " + Person.total);    System.out.println("total = " + Person.total);  }}//輸出://in static block//total=100//total=100

總結(jié):程序中成員變量賦值的執(zhí)行順序

聲明成員變量的默認初始化顯式初始化、多個初始化塊依次被執(zhí)行(同級別下按先后順序執(zhí)行)構(gòu)造器再對成員進行初始化操作通過”對象.屬性”或”對象.方法”的方式,可多次給屬性賦值

四、關(guān)鍵字:final

在Java中聲明類、變量和方法時,可使用關(guān)鍵字final來修飾,表示“最終的”。final標記的類不能被繼承。提高安全性,提高程序的可讀性。String類、System類、StringBuffer類final標記的方法不能被子類重寫。比如:Object類中的getClass()。final標記的變量(成員變量或局部變量)即稱為常量。名稱大寫,且只 能被賦值一次。final標記的成員變量必須在聲明時或在每個構(gòu)造器中或代碼塊中顯式賦值,然后才能使用。final double MY_PI = 3.14;

中國古代,什么人不能有后代,就可以被final聲明,稱為“太監(jiān)類”!

五、抽象類與抽象方法

隨著繼承層次中一個個新子類的定義,類變得越來越具體,而父類則更一 般,更通用。類的設(shè)計應(yīng)該保證父類和子類能夠共享特征。有時將一個父 類設(shè)計得非常抽象,以至于它沒有具體的實例,這樣的類叫做抽象類。

用abstract關(guān)鍵字來修飾一個類,這個類叫做抽象類。用abstract來修飾一個方法,該方法叫做抽象方法。抽象方法:只有方法的聲明,沒有方法的實現(xiàn)。以分號結(jié)束:比如:public abstract void talk();含有抽象方法的類必須被聲明為抽象類。抽象類不能被實例化。抽象類是用來被繼承的,抽象類的子類必須重 寫父類的抽象方法,并提供方法體。若沒有重寫全部的抽象方法,仍 為抽象類。不能用abstract修飾變量、代碼塊、構(gòu)造器;不能用abstract修飾私有方法、靜態(tài)方法、final的方法、final的類。
多態(tài)的應(yīng)用:模板方法設(shè)計模式(TemplateMethod)

抽象類體現(xiàn)的就是一種模板模式的設(shè)計,抽象類作為多個子類的通用模 板,子類在抽象類的基礎(chǔ)上進行擴展、改造,但子類總體上會保留抽象 類的行為方式。

解決的問題:

當功能內(nèi)部一部分實現(xiàn)是確定的,一部分實現(xiàn)是不確定的。這時可以 把不確定的部分暴露出去,讓子類去實現(xiàn)。換句話說,在軟件開發(fā)中實現(xiàn)一個算法時,整體步驟很固定、通用, 這些步驟已經(jīng)在父類中寫好了。但是某些部分易變,易變部分可以抽 象出來,供不同子類實現(xiàn)。這就是一種模板模式。

模板方法設(shè)計模式是編程中經(jīng)常用得到的模式。各個框架、類庫中都有他的 影子,比如常見的有:

數(shù)據(jù)庫訪問的封裝Junit單元測試JavaWeb的Servlet中關(guān)于doGet/doPost方法調(diào)用Hibernate中模板程序Spring中JDBCTemlate、HibernateTemplate等

六、接口(interface)

一方面,有時必須從幾個類中派生出一個子類,繼承它們所有的屬性和方 法。但是,Java不支持多重繼承。有了接口,就可以得到多重繼承的效果。另一方面,有時必須從幾個類中抽取出一些共同的行為特征,而它們之間又 沒有is-a的關(guān)系,僅僅是具有相同的行為特征而已。例如:鼠標、鍵盤、打 印機、掃描儀、攝像頭、充電器、MP3機、手機、數(shù)碼相機、移動硬盤等都 支持USB連接。接口就是規(guī)范,定義的是一組規(guī)則,體現(xiàn)了現(xiàn)實世界中“如果你是/要...則 必須能...”的思想。繼承是一個"是不是"的關(guān)系,而接口實現(xiàn)則是 "能不能" 的關(guān)系。接口的本質(zhì)是契約,標準,規(guī)范,就像我們的法律一樣。制定好后大家都要遵守。接口(interface)是抽象方法和常量值定義的集合。接口的特點:用interface來定義。接口中的所有成員變量都默認是由public static final修飾的。接口中的所有抽象方法都默認是由public abstract修飾的。接口中沒有構(gòu)造器。接口采用多繼承機制。定義Java類的語法格式:先寫extends,后寫implements???class SubClass extends SuperClass implements InterfaceA{ }??一個類可以實現(xiàn)多個接口,接口也可以繼承其它接口。實現(xiàn)接口的類中必須提供接口中所有方法的具體實現(xiàn)內(nèi)容,方可實 例化。否則,仍為抽象類。接口的主要用途就是被實現(xiàn)類實現(xiàn)。(面向接口編程)與繼承關(guān)系類似,接口與實現(xiàn)類之間存在多態(tài)性接口和類是并列關(guān)系,或者可以理解為一種特殊的類。從本質(zhì)上講, 接口是一種特殊的抽象類,這種抽象類中只包含常量和方法的定義 (JDK7.0及之前),而沒有變量和方法的實現(xiàn)。
1.接口的應(yīng)用:代理模式(Proxy)

概述:代理模式是Java開發(fā)中使用較多的一種設(shè)計模式。代理設(shè)計就是為其 他對象提供一種代理以控制對這個對象的訪問。

public interface Network {    public void browse();}//被代理類class RealServer implements Network{    @Override    public void browse() {        System.out.println("真是服務(wù)i其上網(wǎng)瀏覽信息");    }}//代理類class ProxyServer implements Network{    private Network network;    public ProxyServer(Network network) {        this.network = network;    }    public ProxyServer() {    }    public void check(){        System.out.println("檢查網(wǎng)絡(luò)連接");    }    public void browse(){        check();        network.browse();    }}
public class ProxyDemo {    public static void main(String[] args) {        Network net = new ProxyServer(new ProxyServer());        net.browse();    }}
應(yīng)用場景:安全代理:屏蔽對真實角色的直接訪問。遠程代理:通過代理類處理遠程方法調(diào)用(RMI)延遲加載:先加載輕量級的代理對象,真正需要再加載真實對象 比如你要開發(fā)一個大文檔查看軟件,大文檔中有大的圖片,有可能一個圖片有 100MB,在打開文件時,不可能將所有的圖片都顯示出來,這樣就可以使用代理模式,當需要查看圖片時,用proxy來進行大圖片的打開。分類

靜態(tài)代理(靜態(tài)定義代理類)

動態(tài)代理(動態(tài)生成代理類)

JDK自帶的動態(tài)代理,需要反射等知識

2.接口和抽象類之間的對比

No.

區(qū)別點

抽象類

接口

1

定義

包含抽象方法的類

主要是抽象方法和全局常量的集合

2

組成

構(gòu)造方法、抽象方法、普通方法、常量、變量

常量、抽象方法、(jdk:默認方法、靜態(tài)方法)

3

使用

子類繼承抽象類(extends)

子類實現(xiàn)接口(implements)

4

關(guān)系

抽象類可以實現(xiàn)多個接口

接口不能繼承抽象類,只能繼承多個接口

5

常見設(shè)計模式

模板方法

簡單工廠、工廠方法、代理模式

6

對象

都通過對象的多態(tài)性產(chǎn)生實例化對象

都通過對象的多態(tài)性產(chǎn)生實例化對象

7

局限

抽象類有單繼承的局限

接口沒有此局限

8

實際

作為一個模板

只作為一個標準或者是一種能力

9

選擇

如果抽象類和接口都可以使用的話,優(yōu)先使用接口,避免單繼承的局限性

3.Java 8中關(guān)于接口的改進

Java 8中,你可以為接口添加靜態(tài)方法默認方法。從技術(shù)角度來說,這是完 全合法的,只是它看起來違反了接口作為一個抽象定義的理念。

靜態(tài)方法:使用 static關(guān)鍵字修飾。可以通過接口直接調(diào)用靜態(tài)方法,并執(zhí)行 其方法體。我們經(jīng)常在相互一起使用的類中使用靜態(tài)方法。你可以在標準庫中 找到像Collection/Collections或者Path/Paths這樣成對的接口和類。

默認方法:默認方法使用 default關(guān)鍵字修飾??梢酝ㄟ^實現(xiàn)類對象來調(diào)用。 我們在已有的接口中提供新方法的同時,還保持了與舊版本代碼的兼容性。 比如:java 8 API中對Collection、List、Comparator等接口提供了豐富的默認 方法。

4.接口中的默認方法
若一個接口中定義了一個默認方法,而另外一個接口中也定義了一個同名同參數(shù)的方法(不管此方法是否是默認方法),在實現(xiàn)類同時實現(xiàn)了這兩個接口時,會出現(xiàn):接口沖突。解決辦法:實現(xiàn)類必須覆蓋接口中同名同參數(shù)的方法,來解決沖突若一個接口中定義了一個默認方法,而父類中也定義了一個同名同參數(shù)的非 抽象方法,則不會出現(xiàn)沖突問題。因為此時遵守:類優(yōu)先原則。接口中具有 相同名稱和參數(shù)的默認方法會被忽略。

七、類的內(nèi)部成員之五: 內(nèi)部類

當一個事物的內(nèi)部,還有一個部分需要一個完整的結(jié)構(gòu)進行描述,而這個內(nèi)部的完整的結(jié)構(gòu)又只為外部事物提供服務(wù),那么整個內(nèi)部的完整結(jié)構(gòu)最好使用內(nèi)部類。在Java中,允許一個類的定義位于另一個類的內(nèi)部,前者稱為內(nèi)部類,后者稱為外部類。Inner class一般用在定義它的類或語句塊之內(nèi),在外部引用它時必須給出完整的名稱。Inner class的名字不能與包含它的外部類類名相同;分類:成員內(nèi)部類(static成員內(nèi)部類和非static成員內(nèi)部類)局部內(nèi)部類(不談修飾符)、匿名內(nèi)部類成員內(nèi)部類作為類的成員的角色:和外部類不同,Inner class還可以聲明為private或protected;可以調(diào)用外部類的結(jié)構(gòu)Inner class 可以聲明為static的,但此時就不能再使用外層類的非static的成員變量;成員內(nèi)部類作為類的角色:可以在內(nèi)部定義屬性、方法、構(gòu)造器等結(jié)構(gòu)可以聲明為abstract類 ,因此可以被其它的內(nèi)部類繼承可以聲明為final的編譯以后生成OuterClass$InnerClass.class字節(jié)碼文件(也適用于局部內(nèi)部類)

【注意】

非static的成員內(nèi)部類中的成員不能聲明為static的,只有在外部類或static的成員 內(nèi)部類中才可聲明static成員。外部類訪問成員內(nèi)部類的成員,需要“內(nèi)部類.成員”或“內(nèi)部類對象.成員”的方式成員內(nèi)部類可以直接使用外部類的所有成員,包括私有的數(shù)據(jù)當想要在外部類的靜態(tài)成員部分使用內(nèi)部類時,可以考慮內(nèi)部類聲明為靜態(tài)的

內(nèi)部類舉例1

class Outer{    private int s;    public class Inner{        public void mb(){            s=100;            System.out.println("在內(nèi)部類Inner中s=" + s);        }    }    public void ma(){        Inner i = new Inner();        i.mb();    }}public class InnerTest {    public static void main(String[] args) {        Outer2 o = new Outer2();        o.ma();    }}
public class Outer2 {    private int s =111;    public class Inner{        private int s =222;        public void mb(int s){            System.out.println(s);//局部變量s            System.out.println(this.s);//內(nèi)部類對象的屬性s            System.out.println(Outer2.this.s);//外部類對象屬性s        }    }    public static void main(String[] args) {        Outer2 a = new Outer2();        Outer2.Inner b = a.new Inner();        b.mb(333);    }}
如何聲明局部內(nèi)部類
class 外部類{  方法(){    class 局部內(nèi)部類{    }  }  {    class 局部內(nèi)部類{    }  }}
如何使用局部內(nèi)部類只能在聲明它的方法或代碼塊中使用,而且是先聲明后使用。除此之外的任何地方 都不能使用該類但是它的對象可以通過外部方法的返回值返回使用,返回值類型只能是局部內(nèi)部類的父類或父接口類型局部內(nèi)部類的特點內(nèi)部類仍然是一個獨立的類,在編譯之后內(nèi)部類會被編譯成獨立的.class文件,但 是前面冠以外部類的類名和$符號,以及數(shù)字編號。只能在聲明它的方法或代碼塊中使用,而且是先聲明后使用。除此之外的任何地方 都不能使用該類。局部內(nèi)部類可以使用外部類的成員,包括私有的。局部內(nèi)部類可以使用外部方法的局部變量,但是必須是final的。由局部內(nèi)部類和局 部變量的聲明周期不同所致。局部內(nèi)部類和局部變量地位類似,不能使用public,protected,缺省,private局部內(nèi)部類不能使用static修飾,因此也不能包含靜態(tài)成員
匿名內(nèi)部類
匿名內(nèi)部類不能定義任何靜態(tài)成員、方法和類,只能創(chuàng)建匿名內(nèi)部類的一 個實例。一個匿名內(nèi)部類一定是在new的后面,用其隱含實現(xiàn)一個接口或 實現(xiàn)一個類。格式:
new 父類構(gòu)造器(實參列表)|實現(xiàn)接口(){  //匿名內(nèi)部類的類體部分}
匿名內(nèi)部類的特點匿名內(nèi)部類必須繼承父類或?qū)崿F(xiàn)接口匿名內(nèi)部類只能有一個對象匿名內(nèi)部類對象只能使用多態(tài)形式引用
public class Test {    public Test() {        Inner s1 = new Inner();        s1.a = 10;        System.out.println("s1.a" + s1.a);        Inner s2 = new Inner();        s2.a = 20;        System.out.println("s2.a" + s2.a);        Test.Inner s3 = new Inner();        System.out.println(s3.a);    }    class Inner {        public int a =5;    }    public static void main(String[] args) {        Test t = new Test();        Inner r = t.new Inner();        System.out.println(r.a);    }}

拓展:工廠模式

1.無工廠模式
interface car {    void run();}
public class Audi implements car{    public void run(){        System.out.println("Audi is running");    }}
public class BYD implements car{    @Override    public void run() {        System.out.println("BYD running");    }}
public class Client01 {    public static void main(String[] args) {        Audi audi = new Audi();        BYD byd = new BYD();        audi.run();        byd.run();    }}
2.簡單工廠模式
interface Car {    void run();}class Audi implements Car{    @Override    public void run() {        System.out.println("Audi running...");    }}class BYD implements Car {    @Override    public void run() {        System.out.println("BYD running");    }}
class CarFactory {    public static Car getCar(String type) {        if ("Audi".equals(type)){            return new Audi();        }else if ("BYD".equals(type)) {            return new BYD();        }else {            return null;        }    }}
public class Client02 {    public static void main(String[] args) {        Car audi = CarFactory.getCar("Audi");        audi.run();        Car byd = CarFactory.getCar("BYD");        byd.run();    }}

調(diào)用者只要知道他要什么,從哪里拿,如何創(chuàng)建,不需要知道。分工,多出了一 個專門生產(chǎn) Car 的實現(xiàn)類對象的工廠類。把調(diào)用者與創(chuàng)建者分離。

小結(jié):

簡單工廠模式也叫靜態(tài)工廠模式,就是工廠類一般是使用靜態(tài)方法,通過接收的 參數(shù)的不同來返回不同的實例對象。 缺點:對于增加新產(chǎn)品,不修改代碼的話,是無法擴展的。違反了開閉原則(對 擴展開放;對修改封閉)。

3.工廠方法模式

為了避免簡單工廠模式的缺點,不完全滿足 OCP(對擴展開放,對修改關(guān)閉)。 工廠方法模式和簡單工廠模式最大的不同在于,簡單工廠模式只有一個(對于一 個項目或者一個獨立的模塊而言)工廠類,而工廠方法模式有一組實現(xiàn)了相同接 口的工廠類。這樣在簡單工廠模式里集中在工廠方法上的壓力可以由工廠方法模 式里不同的工廠子類來分擔。

interface Car {    void run();}class Audi implements Car {    @Override    public void run() {        System.out.println("Audi is running");    }}class BYD implements Car{    @Override    public void run() {        System.out.println("BYD is running");    }}
//工廠接口public interface Factory {    Car getCar();}class AudiFactory implements Factory {    @Override    public Audi getCar() {        return new Audi();    }}class BydFactory implements Factory {    @Override    public BYD getCar() {        return new BYD();    }}
public class Client {    public static void main(String[] args) {        Car a = new AudiFactory().getCar();        Car b = new BydFactory().getCar();        a.run();        b.run();    }}

總結(jié): 簡單工廠模式與工廠方法模式真正的避免了代碼的改動了?沒有。在簡單工廠模 式中,新產(chǎn)品的加入要修改工廠角色中的判斷語句;而在工廠方法模式中,要么 將判斷邏輯留在抽象工廠角色中,要么在客戶程序中將具體工廠角色寫死(就像 上面的例子一樣)。而且產(chǎn)品對象創(chuàng)建條件的改變必然會引起工廠角色的修改。 面對這種情況,Java 的反射機制與配置文件的巧妙結(jié)合突破了限制——這在 Spring 中完美的體現(xiàn)了出來。

4.抽象工廠模式

==抽象工廠模式和工廠方法模式的區(qū)別就在于需要創(chuàng)建對象的復(fù)雜程度上。==而且抽象工廠模式是三個里面最為抽象、最具一般性的。

抽象工廠模式的用意為:給客戶端提供一個接口,可以創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象。

而且使用抽象工廠模式還要滿足一下條件:

系統(tǒng)中有多個產(chǎn)品族,而系統(tǒng)一次只可能消費其中一族產(chǎn)品。同屬于同一個產(chǎn)品族的產(chǎn)品以其使用。

看過了前兩個模式,對這個模式各個角色之間的協(xié)調(diào)情況應(yīng)該心里有個數(shù)了,我 就不舉具體的例子了

標簽: 工廠模式 抽象方法 匿名內(nèi)部類

上一篇:7.異常處理
下一篇:CodeQL的自動化代碼審計之路(下篇)