人人IT網

人人IT網

當前位置: 主頁 > 編程語言 > C >

JAVA 構造器,extends[繼承],implements[實現],Interface[接口],reflect[反射],clone[克隆],final,static,abstract[抽象]

時間:2012-08-07 00:46來源:Internet 作者:Internet 點擊:
構造器[構造函數]: 在java中如果用戶編寫類的時候沒有提供構造函數,那麼編譯器會自動提供一個默認構造函數.它會把所有的實例字段設置为默認值:所有的數字變量初始化为0;所有的布爾變量設


構造器[構造函數]:

在java中如果用戶編寫類的時候沒有提供構造函數,那麼編譯器會自動提供一個默認構造函數.它會把所有的實例字段設置为默認值:所有的數字變量初始化为0;所有的布爾變量設置为false;所有對象變量設置为null;

PS:

只有在類中沒有其它構造器的時候,系統才會提供默認構造器.如果你希望用戶能能夠調用不帶参數的構造器,那麼你就必須自己實現一個.


extends[繼承]:

java中的繼承,和C++中是有差別的.比如JAVA不支持多重繼承。但是JAVA可以通過implements來實現額外的接口.

Example:

DogDeriveClass extends AnimalBaseClass

{

};

這样DogDeriveClass就全盤繼承了AnimalBaseClass中的所有方法;但是沒有多重繼承,那麼如果還需要其它功能,那麼則可以通過implements關鍵字來實現需要用到的接口.

Example:

DogDeriveClass extends AnimalBaseClass

Implements Shout, Run

{

     void Shot()

     {

     // Do shout something;

     }

    void Run()

    {

    // Do run something;

    }

};

從上面代碼可以看到,雖然JAVA不支持多重繼承,但是派生類可以通過實現接口的方式,來實現本身需要繼承過來的功能.

Implements[實現]:

Implements關鍵字在class聲明中使用,以指示所聲明的類提供了在implements關鍵字後面的名稱所指定的接口中所聲明的所有方法的實現。

接口中的字段[變量]默認是public static final類型; //從接口的調用方式可以看出來. ImplementsInterface.MethedOfInterface();

接口中的方法不能是static,因为static不能被派生類重寫,因为如果接口和派生類中都有一個static同名方法,那麼根據static的調用方式可以看到

Interface.StaticMethed()即可調用,但是Interface中並沒有該方法的實現,只有在具體實現類中有實現,如果有兩個派生類都實現了同名的static方法,則該怎麼調用?

虛擬機也不知道了!!所以不能這麼做.

Example:

public class UserSurfaceView extends SurfaceView 
implements Android.view.SurfaceHolder.Callback  
{

     @Override 

     public void surfaceChanged(SurfaceHolder holder, int format, int with, int heigh)

     {

     //TODO Auto-generated method stub

     }

    @Override

     public void surfaceCreated(SurfaceHolder holder)

     {

     //TODO Auto-generated method stub

     }

     @Override

     public void surfaceDestroyed(SurfaceHolder holder)

     {

     //TODO Auto-generated method stub

     }

};

UserSurfaceView類就要實現SurfaceHolder對象中的Callback接口中所聲明的所有方法的實現: surfaceChanged/surfaceCreated/surfaceDestroyed

從SDK上看到Android.view是包名,SurfaceHolder是一個public的interface, 而Callback就自然是public static interface[從調用方式即可看出來:Android.view.SurfaceHolder.Callback ]


Interface[接口]:

從上面implements關鍵字我們已經大概的了解到了關於java中接口的相關知識,下面看看接口的聲明:

Example:

public interface Android.view.SurfaceHolder.Callback 

{

         void surfaceChanged(SurfaceHolder holder, int format, int with, int heigh);

        void surfaceCreated(SurfaceHolder holder);

        void  surfaceDestroyed(SurfaceHolder holder);

};

由於接口中的方法聲明默認就是public的,因此不需要特意加上public修飾符.


reflect[反射]:

能夠分析類的能力的程序稱为反射器,JAVA中提供此功能的包是java.lang.reflect.它主要是針對工具構建者而不是應用程序員的.如果你只對編寫應用程序感興趣,而不想了解如何編寫供其它java程序員使用的工具,那麼就不要了解該機制.

java的反射機制主要提供了以下功能:

1.在運行時判斷任意一個對象所屬的類;

2.在運行時構造任意一個類的對象;

3.在運行時判斷任意一個類所具有的成員變量和方法[通過反射機制甚至可以調用private方法];

4.在運行時調用任意一個對象的方法;


java.lang.reflect包中包括下面幾個主要:

0.Class類,描述類相關信息;

1.Field類,描述類的字段;

2.Method類,描述類的方法;

3.Constructor類,描述類的構造器;

3.Array類,描述類的創建動態數組的方法,該類中所有的方法都是靜態屬性;


下面我們開始介紹一些具體的用法:

A.Class類:

    在JAVA的Object類中聲明了若幹個可以在所有的JAVA類中改寫的方法:

hashCode()/equals()/clone()/toString()/getClass()等,其中getClass()返回一個Class類型的對象.

    Class類和一般的類一样繼承自Object, 其實體用於表達JAVA程序運行時的class和interface,以及enum, array, primitive, JAVA types和關鍵字void,當加載一個類時,或者當加載器[class loader]的defineClass()被JVM調用,便產生一個Class對象.

    Class是Reflection起源,針對任何你想查看的Class(類),必須先给該類生成一個Class的對象,然後才能通過這個對象調用相應的反射API。

    JAVA提供了多種途徑來为一個Class類生成對應的Class對象:

    A,getClass(): Object類中的方法每個類都擁有該方法.

         Example:

         String str = "Test getClass()";

         Class cl = str.getClass();

    B,Class.getSuperclass(): Class類中的方法,返回該Class的父類的Class;

    C,Class.forName()靜態方法:作用同上;

    D,類名.Class: 作用同上;

    E,primitive wrapper classer的TYPE語法:

        基本類型包裝類的TYPE,Example, Integer.TYPE

        PS: TYPE的使用,只适合原生[基本]數據類型.

B.運行時生成instance

       要生成對象的實體,在反射機制中有兩種方式:

       1.針對不帶参數的構造器;

           Class類中的newInstance()實現該功能;

       2.針對帶参數的構造器;

           Constructor類中的newInstance()方法,實現該功能.首先准備一個Class[]作为Constructor的参數類型.然後調用該Class對象的getConstructor()得到一個專屬的Constructor對象,最後再准備一個Object[]作为Constructor對象裏的newInstance()的實参.

           Example:

           Class c = Class.forName("DynamicTest");

           Class[]  pType = new Class[]{double.class, int.class};

           Constructor ctor = c.getConstructor(pType);

           Object[] obj = new Object[] {new Double(3.14), new Integer(119)};

           Object object = ctor.newInstance(obj);

           System.out.println(object);

 

C. 運行時調用Method:

      首先必須通過Class[]作为getMethod(String name, Class[])方法的参數類型, 然後再通過Object[]存放變量,最後調用Method對象的invoke(Object obj, Object[])方法.

D.運行時調用Field內容:

      修改Field不需要参數和變量, 首先調用Class的getField()方法並制定Field名稱,獲得特定的Field對象後便可以直接調用Field的get(Object obj)和Set(Object obj, Object value)方法.       


克隆[clone]:

其實這個方法的引入,就是为了實現類似C++中深拷貝的功能.在C++中参數的傳遞有:傳值,傳地址,傳引用.

在JAVA中参數傳遞、=的賦值操作都是"引用傳遞[淺拷貝]",因此为了避免誤操作,在需要傳值的時候就不能進行傳引用.

PS:如果類成員變量有數組或者复雜成員時需要進行深度克隆.淺拷貝只复制對象本身,並不复制該對象的引用、指針等成員所指向的地址.

       try{

        classObj = (classObject) super.clone(); // 通常情況下,這一行代碼可以實現普通的克隆.

       }

       catch(CloneNotSupportedException e)

       {

            e.printStackTrace();

       }

        如果classObject類中包含了String name[]成員,那麼就需要進行深度克隆

        try{

        classObj = (classObject)super.clone();

        classObj.name = (String)name.clone();

        }

       catch(CloneNotSupportedException e)

       {

            e.printStackTrace();

       }


final:

一般處於設計和效率的考慮使用final,第一final類不被繼承、方法不被覆蓋.第二final方法會被編譯器在調用final的時候轉入內嵌機制大大提高執行效率.第三防止被修改;

final類不能被繼承,final類不能有子類,final類中的方法默認是final類型.

final方法不能被子類的方法覆蓋,但可以被繼承;

final成員變量表示常量,只能賦值一次,賦值後不能再改變;

final不能修飾構造器;

PS:父類的private方法是不能被子類方法覆蓋的,因为父類的private方法默認是final的;

static:

JAVA中的靜態字段和方法在功能上和C++的靜態字段與方法是相同的.表示屬於一個類而不是屬於此類的任何特定對象的變量和函數.

調用方式:

className.staticMethod();

只要這個類被加載,那麼JAVA虛擬機就能根據類名在運行時的數據區的方法區內找到它們;

靜態字段在內存中只有一個拷貝,JVM只为靜態字段分配一次內存,在加載類的過程中完成對靜態字段的內存分配;


abstract:

抽象類,具有一個或多個抽象方法的類必須被聲明为abstract.通常要盡可能的把通用字段和非常抽象方法移到抽象超類中.


Object類:

Object類是JAVA中所有類的最終的祖先------每一個類都由他擴展而來.


Internal Class內部類:

內部類是定義在其它類內部的類,一般使用內部類有四個原因:

1.內部類對象能夠訪問創建它的對象的實現---包括那些私有數據;

2.內部類能夠隱藏起來,不为同一包中的其它類所見;

3.匿名內部類可以方便的定義運行時回調;

4.使用內部類在編寫事件驅動的程序時用起來很方便;

PS:

本地內部類與匿名內部類的區別在於本地內部類有構造函數,而匿名內部類只能實例初始化。

Example:

      Thread thd = new Thread(

       new A(){//這裏就是一個匿名內部類

                     }

       )

Proxy[代理]:

通過使用代理可以在運行時創建實現一組给定接口的新類.

代理類具有:

指定接口所要求的所有方法;

Object類定義的所有方法(toString, equals等等);

因为我們不能在運行時给這些方法定義新的代碼.你必須提供一個調用處理器.調用處理器是實現了InvocationHandler接口的任意類的對象.該接口只有一個方法:

Object invoke(Object proxy, Method method, Object[] args)

只要調用了代理對象上的任意一個方法,調用處理器的invoke方法就會被調用,帶着Method對象和原調用的参數.隨後調用處理器必須指出如何處理調用.

要創建一個代理對象,我們必須使用proxy類中的newProxyInstance方法,該方法有三個参數:

1>類加載器.

2>一個Class對象數組,每個元素都是需要實現的接口;

3>一個調用處理器;

如何定義處理器?

對結果代理對象能做些什麼?

答案要取决於我們要使用代理機制解决的問題.代理可以用於很多目的:

a.路由對遠程服務器的方法調用;

b.在運行程序中把用戶界面事件和動作關聯起來;

c.为調試目的跟蹤方法調用;

詳細参見:JAVA2核心技術卷1,P225















From:CSDN
頂一下
(0)
0%
踩一下
(0)
0%
------分隔線----------------------------
發表評論
請自覺遵守互聯網相關的政策法規,嚴禁發布色情、暴力、反動的言論。
評價:
表情:
驗證碼:點擊我更換圖片
欄目列表
推薦內容