天天看點

[零基礎學JAVA]Java SE面向對象部分-18.面向對象進階(06)

上季内容回顧:

1、面向對象中接口與抽象類的具體應用。 

  可以通過對象的多态性,為父類執行個體化,之後一切的操作标準以父類為主。

本季主要知識點:

講解抽象類與接口的關系。

1、一個抽象類中能否包含一個接口呢?

abstract class A    

{    

        public abstract void fun();    

        interface B    

        {    

                public void print();    

        }    

}

我們來驗證測試下哈~發現生成A$B.class,表示B作為A的内部接口,證明一個抽象類中可以包含一個内部接口。

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098396cVCw.png"></a>

那怎麼使用呢?我們看下面哈~

首先我們先子類X覆寫父類A方法但不覆寫接口B中的方法

}    

class X extends A    

        //覆寫父類fun()方法    

        public void fun()    

                System.out.println("Hello World!!!");    

發現編譯沒有問題哈~

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098413Eq89.png"></a>

現在我們測試覆寫接口方法哈~

                B b = new Y();    

                b.print();    

        class Y implements B    

                //覆寫父類接口中的方法print()    

                public void print()    

                {    

                System.out.println("Hello Java!!!");    

                }    

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098425aWj3.png"></a>

現在我們加上主方法進行測試哈~

public class Demo01    

        public static void main(String args[])    

                A a = new X();    

                a.fun();    

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098432h5Ss.png"></a>

證明一個抽象類中可以包含一個接口,之後在抽象類的子類中可以有選擇的是否實作抽象類中的接口。

2、一個接口中能否包含一個抽象類呢?同上,都是可以選擇是否實作

interface A    

        public void fun();    

        abstract class B    

                public abstract void print();    

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098436vLRX.png"></a>

下面我們寫上個子類,檢驗一下是否可以有選擇實作抽象類B

class X implements A    

驗證可以哈~

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098448cJPK.png"></a>

下面覆寫抽象類B中print()方法

                new Y().print();    

        class Y extends B    

public class Demo02    

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098459QyvB.png"></a>

3、觀察以下的程式,驗證輸出結果

        public A()    

                this.print();    

        public abstract void print();    

class B extends A    

        private int i = 30;    

        public B(int i)    

                this.i = i;    

        public void print()    

                System.out.println("i = "+i);    

public class Demo03    

                new B(50);    

輸出結果為0哈,這與子類對象執行個體化過程有關哈

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098463bVqe.png"></a>

回顧:子類對象的執行個體化過程 

  · 子類對象使用new關鍵字要調用構造方法 

  ·  調用構造方法時的順序:先去調用父類中的構造方法(預設為無參構造),之後再調用子類中的構造方法。 

  · 調用構造方法的目的:為其内部的屬性初始化 

  · 子類中的屬性在沒有完成父類中的構造方法之前,所有的内容都是預設值,整型是“0” 。

思考: 

  我們知道一個子類如果實作了一個接口則肯定要覆寫接口中的全部抽象方法。那問?是否可以采用一種方式,讓子類可以有選擇的去覆寫自己真正需要的方法。

interface Door    

        //開門    

        public void openDoor();    

        //關門    

        public void closeDoor();    

        //維修    

        public void repairDoor();    

        //拆除    

        public void removeDoor();    

        //鎖門    

        public void lockDoor();    

class D implements Door    

        //子類現在肯定要覆寫裡面全部的抽象方法    

沖突點: 

  · 子類不需要覆寫全部的方法 

  · 如果子類直接實作了接口則肯定要覆寫全部的方法 

  · 解決:如果中間加入了一個過渡端呢? 

   接口  --&gt; 過渡端 --&gt; 子類 

|-  此過渡端不應該被直接使用。 --&gt; 抽象類

過渡端使用抽象類實作最合适,因為抽象類可以實作一個接口同時可以有一些抽象方法,并且不能直接被new關鍵字執行個體化。

abstract class DoorAdapter implements Door    

        //但是以下的方法雖然實作了,可是沒有具體的方法體    

        public void openDoor(){}    

        public void closeDoor(){}    

        public void repairDoor(){}    

        public void removeDoor(){}    

        public void lockDoor(){}    

class D extends DoorAdapter    

        //隻需要打開門    

        public void openDoor()    

                System.out.println("開門~~~");    

public class Demo04    

                new D().openDoor();    

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098467rZxH.png"></a>

此處是有選擇的在子類實作了所需要的方法。這種設計稱為Adapter(擴充卡設計) 

4、模拟: 

  · 張三 很老實  --&gt; 李四,借10000000元,不還 

  · 張三  --&gt; 讨債公司  --&gt; 李四  --&gt; 還錢 

張三和讨債公司的目的 --&gt; 還錢。

//主題:讨債    

interface Subject    

        //完成具體的操作    

        public void giveMe();    

//真正要讨債的人    

class RealSubject implements Subject    

        public void giveMe()    

                System.out.println("還我滴Money");    

//代理人    

class ProxySubject implements Subject    

        private Subject sub = null;    

        public ProxySubject(Subject sub)    

                this.sub = sub;    

        public void before()    

                System.out.println("需要一些準備~~~");    

        public void after()    

                System.out.println("銷毀一些證據~~~");    

                //也要實作讨債    

                this.before();    

                //代表真正的債主去讨債    

                this.sub.giveMe();    

                this.after();    

public class Demo05    

        Subject real = new RealSubject();    

        //委托代理人完成    

        Subject proxy = new ProxySubject(real);    

        proxy.giveMe();    

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_12340984710WT6.png"></a>

代理設計: 

· 主要在日志上比較多。 

· 一般開發中我們隻關注真實主題,而所有的其他操作,比如說日志等操作使用者并不需要知道,是以可以在代理中完成這些其他與具體業務邏輯無直接關系的操作。

接口和抽象類圖的表示? 

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098480XpoH.png"></a>

總結 

面試中:請你詳細的解釋一下抽象類和接口的不同 

<a href="http://redking.blog.51cto.com/attachment/200902/8/27212_1234098496AxDj.png"></a>

#############################################################

本文轉自redking51CTO部落格,原文連結:http://blog.51cto.com/redking/129441,如需轉載請自行聯系原作者

上一篇: [Tools] Volta
下一篇: WinDbg Tools