内部类和设计模式
內(nèi)部類和設(shè)計模式
回顧
1 抽象類:實例化對象沒有意思,所以使用抽象類,抽象類不能實例化2 abstract關(guān)鍵字 abstract 修飾類表示抽象類abstract 修飾方法 抽象方法4 抽象方法抽象方法沒有方法體抽象方法被子類重寫包含抽象方法的類一定是抽象類5 抽象類抽象類不能實例化對象抽象類可以包含抽象方法,也可以包含非抽象方法抽象類的抽象方法必須被子類重寫,除非子類也是抽象類6 static final abstractfinal 和 abstract 不能一起使用static和abstract不能一起使用7接口 :語法:就是特殊的抽象類功能:表示一個約定或能力接口好處:- 擴(kuò)展類的功能,保持對外接口一致 - 接口實現(xiàn)了多重繼承,完成類和任何實現(xiàn)接口子類的通信和交互 - 降低代碼之間的耦合性定義接口 public interface 接口名{靜態(tài)常量抽象方法}jdk1.8 靜態(tài)方法和默認(rèn)方法實現(xiàn)接口class 類名 implements 接口名{重寫接口中抽象方法}一個類可以實現(xiàn)多個接口,只能繼承一個類接口與接口的關(guān)系: extends ,多繼承public interface Inter1{}public interface Inter2{}public interface Inter3 extends Inter1,Inter2{}今天任務(wù)
1.內(nèi)部類1.1 成員內(nèi)部類1.2 局部內(nèi)部類1.3 靜態(tài)內(nèi)部類1.4 匿名內(nèi)部類 2.設(shè)計模式2.1 單例設(shè)計模式2.2 簡單工廠設(shè)計模式教學(xué)目標(biāo)
1.了解成員內(nèi)部類、局部內(nèi)部類和靜態(tài)內(nèi)部類的語法結(jié)構(gòu) 2.了解各種內(nèi)部類的注意事項 3.掌握匿名內(nèi)部類的使用 4.掌握單例設(shè)計模式的實現(xiàn) 5.掌握簡單工廠設(shè)計模式的實現(xiàn)第一節(jié) 內(nèi)部類
內(nèi)部類:一個類中嵌套(包含)另外一個類。包含的類叫內(nèi)部類,外層類叫外部類。
成員內(nèi)部類:
局部內(nèi)部類:
靜態(tài)內(nèi)部類:
匿名內(nèi)部類:
#####1.1 成員內(nèi)部類
作為外部類的成員存在,與成員變量和成員方法平級關(guān)系。
1.1.1 聲明: public class Out{//成員變量//成員方法//成員內(nèi)部類訪問權(quán)限 class In{//成員變量//成員方法} } 1.1.2 語法說明: 成員內(nèi)部類的訪問權(quán)限:任意的1.1.3 如何創(chuàng)建成員內(nèi)部類的對象:由于成員內(nèi)部類作為外部類的成員存在,若想訪問類成員需要通過對象,所以成員內(nèi)部類對象需要通過外部類 對象創(chuàng)建語法://創(chuàng)建外部類對象Out o = new Out();//通過外部類找到內(nèi)部類,通過外部類對象創(chuàng)建內(nèi)部類對象Out.In i = o.new In();一步完成:Out.In i2=new Out().new In();1.1.4 如何在成員內(nèi)部類中訪問外部類的成員:1.當(dāng)外部類的屬性和內(nèi)部類屬性不同名時,可以直接訪問2.當(dāng)外部類屬性與內(nèi)部類屬性同名時,格式:外部類名.this.屬性名通過以上格式在內(nèi)部類中訪問外部類的同名屬性3.成員內(nèi)部類中不能包含靜態(tài)成員 1.1.5 成員內(nèi)部類的字節(jié)碼文件格式:外部類名$內(nèi)部類名.class代碼實現(xiàn):
public class Out {//成員變量int a = 2;//成員方法public void fun() {System.out.println(a);}//成員內(nèi)部類public class In{//成員內(nèi)部類的成員變量int a = 3;//成員內(nèi)部類的成員方法public void fun() {Out.this.fun();System.out.println(a);System.out.println(Out.this.a);}} }import memberInnerClass.Out.In; public class Test {public static void main(String[] args) {//先創(chuàng)建外部類對象Out o = new Out();//System.out.println(o.a);//o.fun(); //創(chuàng)建成員內(nèi)部類的對象//通過外類的對象創(chuàng)建成員內(nèi)部類對象In i = o.new In();//System.out.println(i.b);i.fun();} }#####1.2 局部內(nèi)部類
作為局部成員存在,和局部變量平級。
1.2.1 聲明: public class Outer{//成員變量//成員方法//局部內(nèi)部類所在的方法public void fun(){//功能代碼//局部內(nèi)部類訪問權(quán)限 class Inner{//局部內(nèi)部類的成員變量//局部內(nèi)部類的成員方法}} } 1.2.2 說明: 局部內(nèi)部類的訪問權(quán)限:只能是默認(rèn)1.2.3 如何創(chuàng)建局部內(nèi)部類對象: 直接在局部內(nèi)部類所在的方法中創(chuàng)建對象并調(diào)用方法1.2.4 如何在局部內(nèi)部類中訪問外部類的屬性:1.不同名,直接訪問2.同名,外部類名.this.屬性名3 局部內(nèi)部類中不能包含靜態(tài)成員。4 局部內(nèi)部類中訪問局部變量,局部變量必須是final 常量 ,從jdk1.8之后final可以省略 1.2.5 字節(jié)碼文件:外部類名$編號內(nèi)部類名.class代碼實現(xiàn):
public class Outer {//成員變量int a = 3;//成員方法public void fun() {class Inner{}System.out.println("外部類的fun");}//局部內(nèi)部類所在的方法public void fun3() {class In{}//局部內(nèi)部類class Inner{//成員變量int a = 10;//成員方法public void fun() {Outer.this.fun();System.out.println(a);System.out.println(Outer.this.a);System.out.println("局部內(nèi)部類的fun方法");}}Inner i = new Inner();i.fun();} }public class Test {public static void main(String[] args) {Outer o = new Outer();//局部內(nèi)部類具有作用域,所以調(diào)用外部類對象的fun3方法時會聲明局部內(nèi)部類并創(chuàng)建對象調(diào)用方法o.fun3();} }#####1.3 靜態(tài)內(nèi)部類(重點)
static關(guān)鍵字用法:修飾成員變量,成員方法,代碼塊 static關(guān)鍵字的第四個用法,修飾內(nèi)部類(有要求的) static修飾的內(nèi)部類是靜態(tài)內(nèi)部類 static只能修飾類成員 使用static修飾的成員內(nèi)部類是靜態(tài)內(nèi)部類1.3.1 聲明: public class Out{ 訪問權(quán)限 static class In{} } 1.3.2 說明: 訪問權(quán)限:任意的,一般使用public 使用static修飾的內(nèi)部類,自動提升為普通類,相當(dāng)于一個獨立的類,和外部類級別相同1.3.3 創(chuàng)建對象: 不需要外部類的對象,可以直接創(chuàng)建靜態(tài)內(nèi)部類的對象格式:外部類.內(nèi)部類 標(biāo)識符 = new 外部類.內(nèi)部類構(gòu)造方法1.3.4 訪問外部類的成員:1 靜態(tài)內(nèi)部類能直接訪問外部類的靜態(tài)成員2 非靜態(tài)的成員只能通過創(chuàng)建外部類對象訪問3 靜態(tài)內(nèi)部類中可以包含靜態(tài)成員1.3.5 字節(jié)碼文件格式:外部類名$內(nèi)部類名.class(與成員內(nèi)部類一樣)代碼實現(xiàn):
public class OuterClass {static String s = "hello";int a = 10;public void fun() {System.out.println("外部類的fun");}//靜態(tài)內(nèi)部類public static class InnerClass{int b = 20;public void fun() {System.out.println(s);System.out.println();System.out.println("內(nèi)部類的fun");}} }import staticInnerClass.OuterClass.InnerClass; public class Test {public static void main(String[] args) {//可以不創(chuàng)建外部類對象,直接創(chuàng)建靜態(tài)內(nèi)部類對象InnerClass i = new InnerClass();i.fun(); } }#####1.4 匿名內(nèi)部類
1.4.1 什么是匿名內(nèi)部類:沒有名字的內(nèi)部類 1.4.2 原理產(chǎn)生原因:由于接口和抽象類不能創(chuàng)建對象,若一個接口的實現(xiàn)類只需要使用一次,或一個抽象類的子類只需要使用一次,可以使用匿名內(nèi)部類,匿名內(nèi)部類只能創(chuàng)建一個對象代碼實現(xiàn):
public interface I {public abstract void fun(); }public class Test{public static void main(Strng[]args){I i = new I(){public void fun(){//功能代碼}};i.fun1();//使用匿名內(nèi)部類的對象(接口引用)調(diào)用匿名內(nèi)部類中重寫的接口中的方法} } 1.4.3 匿名內(nèi)部類的注意事項:1 匿名內(nèi)部類中必須把抽象方法全部實現(xiàn) 2 匿名內(nèi)部類中可以聲明獨有的屬性和方法,但是由于接口引用不能訪問實現(xiàn)類中獨有的屬性和方法,所以一般不在匿名內(nèi)部類中聲明獨有的屬性和方法 3 匿名對象:若在匿名內(nèi)部類中聲明了獨有的方法或?qū)傩?#xff0c;可以使用匿名對象訪問,不能通過對象名.方法名()訪問。1.4.4 lambda 表達(dá)式 入門使用 USB leishe= ()->System.out.println("鐳蛇和電腦連接成功,開始工作");代碼實現(xiàn):
public static void main(String[]args){//匿名對象調(diào)用成員方法new I(){public void fun(){}public void fun1(){System.out.println("匿名內(nèi)部類的fun1");}}.fun1();//使用匿名內(nèi)部類的匿名對象調(diào)用匿名內(nèi)部類中獨有的方法//new Animal().eat(); } 1.4.4 匿名內(nèi)部類的字節(jié)碼文件格式:測試類$編號.class匿名內(nèi)部類只能使用一次,即便兩次聲明的匿名內(nèi)部類完全一致,也是兩個匿名內(nèi)部類####第二節(jié) 設(shè)計模式
設(shè)計模式
? 設(shè)計模式是軟件開發(fā)人員在軟件開發(fā)過程中面臨的一般問題的解決方案。這些解決方案是眾多軟件開發(fā)人員經(jīng)過相當(dāng)長的一段時間的試驗和錯誤總結(jié)出來的。
? 簡單理解:特定問題的特定解決方法。
#####2.1 單例設(shè)計模式
2.1.1 什么是單例:在程序運行,一個類只需要一個實例,不能出現(xiàn)多個實例,就叫單例。2.1.2 單例的模式動機(jī):在一個系統(tǒng)或平臺中,某個類的實例(對象),只需要有一個一個朝代只能有一個皇帝,一個公司只能有一個老板2.1.3 實現(xiàn)原理:封裝得到一個類的對象,需要通過new關(guān)鍵字,調(diào)用構(gòu)造方法創(chuàng)建對象實現(xiàn)過程:分析:某個類只能有一個對象,但是構(gòu)造方法只要一調(diào)用就會產(chǎn)生新的對象,可以通過封裝將構(gòu)造方法進(jìn)行私有化;若構(gòu)造方法私有化,那么此類將沒有對象私有化的構(gòu)造方法可以在類內(nèi)部調(diào)用創(chuàng)建對象2.1.4 需要完成的事項:1)私有化構(gòu)造方法;2)在類內(nèi)創(chuàng)建對象;3)提供一個共有的方法,用來獲取本類對象2.1.5 實現(xiàn)方式:單例分為懶漢式和餓漢式核心:構(gòu)造方法私有:不能在類外隨意創(chuàng)建對象在類內(nèi)部聲明一個本類靜態(tài)的對象作為屬性提供一個共有靜態(tài)的方法用來獲取本類對象餓漢式代碼實現(xiàn):
public class Boss{//屬性private String name;private int age;//私有化構(gòu)造方法private Boss(String name, int age){this.name = name;this.age = age;}//私有靜態(tài)本類對象作為屬性private static Boss boss = new Boss("馬云",12);//提供共有靜態(tài)方法獲取本類對象public static Boss getBoss(){return boss;} }懶漢式代碼實現(xiàn):
pulbic class King{//屬性private String name;private int age;//私有構(gòu)造方法private King(String name, int age){this.name = name;this.age = age;}//私有靜態(tài)本類對象private static King king;//共有靜態(tài)方法獲取本類對象public static King getKing(){if(king==null){king = new King("唐太宗",12);}return king;} } 思考:懶漢式和餓漢式有什么區(qū)別? 書寫上的區(qū)別:懶漢是調(diào)用方法是初始化對象,餓漢是聲明同時初始化 使用上沒有區(qū)別 存儲時:在第一次獲取單例類對象前,懶漢比餓漢節(jié)省空間 多線程操作時區(qū)別:懶漢式存在線程安全問題,餓漢式不存在2.2 簡單工廠設(shè)計模式
1.原理:多態(tài)
生活中的工廠:手機(jī)廠,電視廠,服裝廠…
2.動機(jī):
? 考慮一個簡單的軟件應(yīng)用場景,一個軟件系統(tǒng)可以提供多個外觀不同的按鈕(如圓形按鈕、矩形按鈕、菱形按鈕等),這些按鈕都源自同一個基類,不過在繼承基類后不同的子類修改了部分屬性從而使得它們可以呈現(xiàn)不同的外觀,如果我們希望在使用這些按鈕時,不需要知道這些具體按鈕類的名字,只需要知道表示該按鈕類的一個參數(shù),并提供一個調(diào)用方便的方法,把該參數(shù)傳入方法即可返回一個相應(yīng)的按鈕對象,此時,就可以使用簡單工廠模式。
3.優(yōu)缺點:
? 優(yōu)點:工廠類包含產(chǎn)品的判斷邏輯,可以決定創(chuàng)建哪一個產(chǎn)品類的實例,客戶端可以免除直接創(chuàng)建產(chǎn)品對象的責(zé)任,而僅僅“消費”產(chǎn)品;簡單工廠模式通過這種做法實現(xiàn)了對責(zé)任的分割,它提供了專門的工廠類用于創(chuàng)建對象。
? 缺點:由于工廠類集中了所有產(chǎn)品創(chuàng)建邏輯,一旦不能正常工作,整個系統(tǒng)都要受到影響。使用簡單工廠模式將會增加系統(tǒng)中類的個數(shù),在一定程序上增加了系統(tǒng)的復(fù)雜度和理解難度。系統(tǒng)擴(kuò)展困難,一旦添加新產(chǎn)品就不得不修改工廠邏輯,在產(chǎn)品類型較多時,可能造成工廠邏輯過于復(fù)雜,不利于系統(tǒng)的擴(kuò)展和維護(hù)。
4.案例:
服裝廠:生產(chǎn)服裝
分析:
需要一個服裝廠類:工廠,類中具有生產(chǎn)服裝的功能(創(chuàng)建服裝對象)
服裝類(父類產(chǎn)品):抽象類表示
服裝子類(具體產(chǎn)品): 普通類表示
客戶程序:使用工廠的程序。
總結(jié)
1 內(nèi)部類 1.1 成員內(nèi)部類成員內(nèi)部類和非靜態(tài)屬性、方法 級別相同注意:成員內(nèi)部類可以直接訪問外部類的非靜態(tài)的屬性和方法成員內(nèi)部類可以訪問外部類的靜態(tài)屬性和方法成員內(nèi)部類中屬性及方法和外部類的屬性及方法相同時使用 外部類名.this.屬性|方法成員內(nèi)部類中不能包含靜態(tài)屬性和方法1.2 局部內(nèi)部類局部內(nèi)部類,是包含在方法中,使用范圍只限制在方法內(nèi)。注意:局部內(nèi)部類可以直接訪問外部類的非靜態(tài)的屬性和方法局部內(nèi)部類可以訪問外部類的靜態(tài)屬性和方法如果局部內(nèi)部類中屬性及方法和外部類的屬性及方法相同 外部類名.this.屬性|方法局部內(nèi)部類不能包含靜態(tài)屬性和方法局部內(nèi)部類使用局部變量,局部變量必須是常量 final修飾1.3 靜態(tài)內(nèi)部類靜態(tài)內(nèi)部類:相當(dāng)于一個外部類只有內(nèi)部類才可以是靜態(tài)的注意:靜態(tài)內(nèi)部類可以直接訪問外部類的靜態(tài)屬性和方法靜態(tài)內(nèi)部類不能直接訪問外部類的非靜態(tài)屬性和方法,需要創(chuàng)建對象訪問靜態(tài)內(nèi)部類中可以包含靜態(tài)成員1.4 匿名內(nèi)部類匿名內(nèi)部類就是內(nèi)部類的簡寫,主要用在接口中創(chuàng)建對象 Usb mouse=new Usb(){public void service(){}};mouse.service();2 設(shè)計模式:特定問題的特定解決方法 2.1 單例設(shè)計模式 : 懶漢式 餓漢式1 私有化構(gòu)造方法2 在類內(nèi)部創(chuàng)建一個靜態(tài)對象3 通過一個公開的方法返回這個對象2.2 簡單工廠設(shè)計模式: 把對象的創(chuàng)建交給一個獨立的工廠類創(chuàng)建。把對象的創(chuàng)建和使用分隔開1 父類產(chǎn)品2 子類產(chǎn)品3 工廠4 客戶程序默寫
設(shè)計一個抽象商品類,具有名稱和產(chǎn)地屬性非抽象食品類,繼承商品類非抽象日用品類,繼承商品類設(shè)計一個工具類,判斷一件商品是食品還是日用品,若是食品輸出“可以食用”,若是日用品輸出“不可以食用”作業(yè)
1.使用懶漢式實現(xiàn)單例設(shè)計模式
2.編寫面包類,包含三個方法
? prepare()準(zhǔn)備
? bake()烘烤
? box打包
三個子產(chǎn)品:雞蛋面包,奶油面包,雞腿面包
面包工廠類:負(fù)責(zé)生產(chǎn)各種面包
使用簡單工廠實現(xiàn)。
作業(yè)答案關(guān)注 +私信哦
面試題
//要求:使用已知的變量,在控制臺輸出30,20,10。class Outer {public int num = 10;class Inner {public int num = 20;public void show() {int num = 30;System.out.println(num); System.out.println(this.num);System.out.println(Outer.this.num); }}}class InnerClassTest {public static void main(String[] args) {Outer.Inner oi = new Outer().new Inner();oi.show();} }總結(jié)
- 上一篇: 【报告分享】第二届中国工业互联网大赛成果
- 下一篇: Prometheus 实战于源码分析之w