java面向對象--06

static關鍵字

靜態:static
用法:是一個修飾符,用於修飾成員(成員變量,成員函數)(只能修飾成員,不能修飾局部)
當成員被靜態修飾後,就多了一個調用方式,除了可以被對象調用外,
還可以直接被類名調用。類名.靜態成員

static的特點:
1.隨着類的加載而加載
也就是說,靜態會隨着類的消失而消失。說明它的生命週期最長
2.優先於對象存在
所以纔會直接用類名調用,當時對象還不存在
明確一點:靜態是先存在的,對象是後存在的
3.被所有對象所共享
4.可以直接被類名所調用

class person
{
    String name;//成員變量,實例變量。(對象的變量)對象存在才存在
    static String country = "CN";//靜態的成員變量,類變量。類存在就存在

}

class staticDemo
{
    public static void main(String[] args)
    {
        System.out.println(person.country);//類名.靜態成員
    }
}

實例變量和類變量的區別
1.存放位置
類變量隨着類的加載而存在於方法區中。
實例變量隨着對象的建立而存在於堆內存中。
2.生命週期
類變量生命週期最長,隨着類的消失而消失
實例變量生命週期隨着對象的消失而消失

靜態的使用注意事項:
1.靜態方法只能訪問靜態成員,方法
非靜態方法既可以訪問靜態,也可以訪問非靜態
2.靜態方法中不可以定義this,super關鍵字
因爲靜態優先於對象存在,所以靜態方法中不可以出現this
3.主函數是靜態的

靜態有利有弊
利:對對象的共享數據進行單獨空間的存儲,節省空間。沒有必要每個對象都存儲一份
可以直接被類名調用

弊:生命週期過長
訪問出現侷限性(靜態雖好,只能訪問靜態)

main函數

public static void main(String[] args) 虛擬機只要這個主函數

主函數:是一個特別的函數,作爲程序的入口,可以被jvm調用
它是程序的起始點

主函數的定義:
public:代表着該函數訪問權限是最大的
static:代表主函數隨着類的加載就已經存在了
void:主函數沒有具體的返回值
main:不是關鍵字,但是是一個特殊的單詞,可以被jvm識別
(String[] args):函數的參數,參數類型是一個數組,該數組中的元素是字符串。也就是字符串類型的數組。

主函數是固定格式的:jvm識別

jvm在調用主函數時,傳入的是new String[0];

class mainDemo
{
    public static void main(int x)//函數名相同,參數列表不一樣 重載
    {

    }

    public static void main(String[] args,int x)
    {
        System.out.println();
    }
    public static void main(String[] args){}
}

什麼時候使用靜態?

要從兩方面下手:
因爲靜態修飾的內容有成員變量和成員函數
什麼時候定義靜態變量(類變量)呢?
當對象中出現共享數據時,該數據被靜態修飾。
對象中的特有數據要定義成非靜態存在於堆內存中

什麼時候定義靜態函數呢?
當功能內部沒有訪問到非靜態數據(對象的特有數據),
那麼該功能可以定義成靜態的。

靜態的應用

每一個應用程序中都有共性的功能,
可以將這些功能進行抽取,獨立封裝
以便複用。

雖然可以通過建立ArrayTool的對象使用這些工具方法,對數組進行操作
發現了問題:
1,對象是用於封裝數據的,可是ArrayTool對象並沒有封裝特有數據
2,操作數組的每一個方法都沒有用到ArrayTool對象中的特有數據

這時就考慮,讓程序更嚴謹,是不需要對象的
可以將ArrayTool中的方法都定義成靜態的,直接通過類名調用即可

將方法都靜態後,可以方便使用,但是該類還是可以被其他程序建立對象的
爲了更加嚴謹,強制讓該類不能建立對象
可以通過將構造函數私有化完成。

接下來,將ArrayTool.class文件發送給其他人,其他人只要將該文件設置到classpath路徑下,就可以使用該工具類
但是很遺憾,該類中到底定義了多少個方法,對方卻不清楚。因爲該類並沒有使用說明書。
開始製作程序的說明書。java的說明書通過文檔註釋來完成。

public class ArrayTool
{
    /**
    空參數構造函數。
    */

    private ArrayTool(){}  //私有化

    /**
    獲取一個整型數組的最大值
    @param arr 接受一個int類型的數組
    @return 會返回一個該數組的最大值
    */
    public static int getMax(int[] arr)
    {
        int max = 0;
        for(int x= 1;x<arr.length;x++)
        {
            if(arr[x]>arr[max])
                max = x;
        }
        return arr[max];
    }

    /**
    獲取一個整型數組的最小值
    @param arr 接受一個int類型的數組
    @return 會返回一個該數組的最小值
    */
    public static int getMin(int[] arr)
    {
        int min = 0;
        for(int x=1;x<arr.length;x++)
        {
            if(arr[x]<arr[min])
                min = x;
        }
        return arr[min];
    }

    /**
    給int數組進行選擇排序。
    @param arr 接受一個int類型的數組
    */
    public static void selectSort(int[] arr)
    {
        for (int x=0;x<arr.length;x++)
        {
            for(int y=x+1;y<arr.length;y++)
            {
                if(arr[x]>arr[y])
                {
                    swap(arr,x,y);
                }
            }
        }
    }
    /**
    給int數組進行冒泡排序。
    @param arr 接受一個int類型的數組
    */
    public static void bubbleSort(int[] arr)
    {
        for(int x=0;x<arr.length;x++)
        {
            for(int y=0;y<arr.length-x-1;y++)
            {
                if(arr[y]>arr[y+1])
                {
                    swap(arr,y,y+1);
                }
            }
        }
    }
    /**
    給數組中的元素進行位置的置換
    @param arr 接受一個int類型的數組
    @param a 要置換的位置
    @param b 要置換的位置
    */

    private static void swap(int[] arr,int a,int b)
    {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

    /**
    用於打印數組中的元素,打印形式是:[elemet1 ,elemet2 , ...]
    */
    public static void printArray(int[] arr)
    {
        System.out.print("[");
        for(int x=0;x<arr.length;x++)
        {
            if(x!=arr.length-1)
                System.out.print(arr[x]+",");
            else
                System.out.println(arr[x]+"]");
        }
    }
}


/*
class Demo
{
    public static void main(String[] args)
    {
        //int[] arr = {3,4,1,8};

        int[] arr = {3,4,19,8};

        int max = getMax(arr);

        System.out.println("max="+max);
    }
    public static int getMax(int[] arr)
    {
        int max = 0;
        for(int x= 1;x<arr.length;x++)
        {
            if(arr[x]>arr[max])
                max = x;
        }
        return arr[max];
    }

}

一個類中默認會有一個空參數的構造函數
這個默認的構造函數的權限和所屬類一致
這個類被public修飾,那麼默認的構造函數也帶public修飾符
如果類沒有被public修飾,那麼默認的構造函數也沒有被public修飾。

靜態代碼塊

靜態代碼塊
格式:
static
{
靜態代碼塊中的執行語句。
}

特點:隨着類的加載而執行,只執行一次,並優先於主函數。
用於給類進行初始化

class StaticCode
{
    static
    {
        System.out.println("a");
    }
}

class StaticCodeDemo
{
    static
    {
        System.out.println("b");
    }
    public static void main(String[] args)
    {
        new StaticCode();
        new StaticCode();//第二次不執行
        System.out.println("over");
    }
    static
    {
        System.out.println("c");
    }
}

打印結果:b c a over

person p = new person(“zhangsan”,20);
這句話都做了什麼事情?
1,因爲new用到了person.class所以會先找到person.class文件並加載到內存中。
2,執行該類中的static代碼塊(如果有的話),給person.class類進行初始化。
3,在堆內存中開闢出空間,分配內存地址
4,在堆內存中建立對象的特有屬性,並進行默認初始化
5,對屬性進行顯示初始化
6,對對象進行構造代碼塊初始化
7,對對象進行對應的構造函數初始化
8,將內存地址賦給內存中的P變量

初始化順序:
靜態代碼塊初始化>默認初始化>顯示初始化>構造代碼塊初始化>構造函數初始化

單例設計模式

設計模式:解決某一類問題最行之有效的方法
java中有23種設計模式:其中一種
單例設計模式:解決一個類在內存中只存在一個對象

想要保證對象唯一。
1,爲了避免其他程序過多建立該類對象。先禁止其他程序建立該類對象
2,還爲了讓其他程序可以訪問到該類對象,只好在本類中,自定義一個對象
3,爲了方便其他程序對自定義對象的訪問,可以對外提供一些訪問方式

這三部用代碼體現:
1,將構造函數私有化
2,在類中創建一個本類對象
3,提供一個方法可以獲取到該對象

對於事物該怎麼描述,還怎麼描述
當需要將該事物的對象保證在內存中唯一時,就將以上的三步加上即可。

class Single
{

    private Single(){}                         //1

    private static Single s = new Single();    //2

    public static Single getInstance()         //3
    {
        return s;
    }
}

class SingleDemo
{
    public static void main(String[] args)
    {
        Single ss = Single.getInstance();
    }
}

這個是先初始化對象。
稱爲:餓漢式。
Single類一進內存,就已經創建好了對象
開發一般用餓漢式

class Single
{
    private static Single s = new Single();
    private Single(){}
    public static Single getInstance()
    {
        return s;
    }
}

對象是方法被調用時,才初始化,也叫做對象的延時加載。
稱爲:懶漢式。
Single類進內存,對象還沒有存在,只有調用了getInstance方法時,才建立對象。

class Single
{
    private static Single s = null;
    private Single(){}
    public static Single getInstance()
    {
        if(s==null)
            s = new Single();
        return s;
    }
}

原則:定義單例,建議使用餓漢式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章