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