面向對象(2)

 

//static(靜態)關鍵字               

         作爲一個修飾符存在。對變量進行修飾作用,起到特別含義。

         用法:是一個修飾符,用於修飾成員中都有的共性的東西(成員變量和成員函數),不能用來修飾局部。起到節約內存的作用。所有對象共享一個靜態數據。

         修飾之後的變量就不在堆內存中了,單獨提取出來,每個對象都能訪問得到。被所有對象所共享,可以起到節約內存的作用。

         當成員被靜態修飾後,就多了一種調用方式,除了可以被對象調用外,還可以直接被類名調用,寫法格式是“類名.靜態成員”。

         特有內容隨着對象存儲,不可以用靜態修飾。

//內存中的方法區(或者叫共享區/數據區):這片區裏面還會有更細緻的劃分。

         類中的方法,類中的共享數據都存放在這裏。

         其實是類的東西都放在方法區中,方法區裏有靜態區和非靜態區。

         而且內存加載的順序是先類,再對象,即先方法區,再堆內存。先靜態區,再非靜態區。

//static的特點:

         1、隨着類的加載而加載,隨着類的消失而消失;說明他的生命週期最長;對內存一直佔有空間,故不建議定義過度的靜態變量,浪費內存。

         2、優先於對象存在,可以沒有建立對象而存在;需要用可以通過類調用或者建立對象後用對象調用。

         3、被所有對象所共享,

         4、可以直接被類名所調用。

 

         //對象沒有建立之前,是不可能有裏面的元素出現的。就算在類中有定義一個變量,因爲沒被賦值,沒有實際意義,所以是不會在內存中有出現,只有對象建立後,賦予了內容纔會有意義,纔會在內存中出現。除非是靜態的成員變量。

 

//靜態變量,非靜態變量;成員變量,實例變量(實例就是對象,也可說爲對象變量);靜態的成員變量,類變量。

 

//實例變量和類變量的區別。

1、存放位置不同,類變量隨着類的加載而存在於方法區中;實例變量隨着對象的建立而存在於堆內存中;

2、生命週期不同;類變量生命週期最長。隨着類的消失而消失;實例變量生命週期隨着對象的消失而消失。

 

//靜態的使用注意事項

1、靜態方法只能訪問靜態成員(變量和方法)。沒有被對象調用的非靜態方法也是訪問不到。

2、非靜態方法既可以訪問靜態也可以訪問非靜態。

3、靜態方法中不可以定義this super關鍵字,因爲靜態優先於對象的存在,所以靜態方法中不可以出現this。

 

靜態隨類先存在,非靜態隨對象而存在。

 

靜態有利有弊

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

調用者只有兩,對象和類。

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

 

注意:主函數是靜態的。

 

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

 

主函數的定義:

public:代表着該函數的訪問權限是最大的;

static:代表着主函數隨着類的加載已經存在了;不需要再去調用了。jvm就默認你調用了。

void:主函數沒有具體的返回值。 

就是jvm在調用主函數。

main:不是關鍵字,但是是一個特殊的單詞,可以被jvm識別。                          

關鍵字是不能用在函數名稱的。

(String[] arr): 函數的參數,參數類型是一個數組,該數組中的元素是字符串,字符串類型的數組。存儲字符串類型元素的數組。

 

主函數是固定格式的,纔可以被jvm識別,只有後面一個變量名纔可以被改寫,他是一個變量名,可以隨意改寫的。   arguments 參數很多參數的意思。

 

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

 

 

我們在調用函數時,是要往裏面傳與之對應的參數。現在的問題是jvm在調用main時到底調用的是什麼呢?

 

引用數據類型無非就指向兩個值,一個具體的,或者一個空null。

 

javac 啓動的是編譯器,java啓動的是jvm

 

//什麼時候使用靜態。

 

要從兩個方面下手:

因爲靜態修飾的內容有成員變量和函數,

 

什麼時候定義靜態變量(類變量)呢?

當對象中的出現共享數據時,該數據被靜態所修飾,對象中的特有數據要定義成非靜態存在於堆內存中。

共享數據/對象的特有數據。

 

什麼時候定義靜態函數呢?

當功能內部沒有訪問到非靜態數據(或說對象的特有數據),那麼該功能可以定義爲靜態的。

 

//靜態的應用

 

把多個類中的同樣的功能抽取出來封裝到一個類當中。

功能的封裝,

先把功能變成對象後,拿到了對象就拿到了這些功能。這就叫功能封裝。

先把複用的功能做出來,以後的類就可以重複使用這些功能了。

 

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

 

封裝主要是封裝成員(屬性和功能)對象可以是任何的屬性或者功能。

 

雖然可以通過建立arraytool的對象使用這些工具方法,對數組進行操作。

發現了的問題:

1、對象是用於封裝數據的,可是arraytool對象並未封裝特有數據,

2、操作數組的每一個方法都沒有用到arraytool的對象的特有數據,

這是就考慮,讓程序更嚴謹,是不需要對象的。

可以將arraytool中的方法都定義成static的,直接通過類名調用即可。

 

這個就叫做工具類,通常情況下,工具類都是定義的靜態的。

 

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

 

還有一定要把能隱藏的功能和屬性都隱藏起來。只把必須要公開的功能去公開。

 

 

//開發要養成習慣,都寫說明書

 

接下來,將arraytool.class文件其他人,其他人只要將該文件設置到classpath的路徑下,就可以使用該工具類,但是,很遺憾,該類中到底定義了多少個方法,對方都不清楚,因爲該類沒有使用說明書。

開始製作程序的說明書,java的說明書通過文檔註釋來完成。如:

 

/**

類的描述信息:

這是一個可以對數組進行操作的工具類,該類中提供了,獲取最值,排序等功能。

(文檔註釋裏有些特殊的標示,是可以直接被文檔工具所提取並識別的)

@author 張三

@version v1.1

 

接下來就是對程序的功能進行描述

凡是public的修飾符都用文檔註釋描述,因爲都可以被文檔註釋工具所提取。

 

。。。。。。。。。。。

*/

一個類中默認的會有一個空參數的構造函數,是系統自動生成的。

這個默認的構造函數的權限和所屬類一致,如果類被public修飾,那麼默認的構造函數也帶public修飾符,如果類沒有被public修飾,那麼默認的構造函數,也沒有被普遍了修飾,

 

默認構造函數的權限是隨着類的變化而變化的。默認是看不見的。寫了就沒有默認了。

 

api幫助文檔,應用程序接口文檔。

 

工具類。

 

//靜態代碼塊:

 

格式:

static

         靜態代碼塊的執行語句;

靜態代碼快的特徵,隨着類的加載而執行,只執行一次,並優先於主函數執行,因爲他沒有名字不需要調用,所以就直接執行。已經加進入內存了,如再被調用也不需要再加載了,就算引用也不會被執行了。

用於給類進行初始化的。一個類進內存不需要對象的情況下,這個類先要做些什麼事情,相對的少用一些。

 

調用類的功能要會被加載,只要在用到他當中的功能纔會被加載,否則是不會被加載的。

 

建立一個對象,賦值的順序是:默認初始化,——顯示初始化——構造代碼塊初始化——構造函數初始化。

只要靜態代碼塊執行完後,對象纔會開闢空間和分配地址值。

 

Person p= new Person(“張三”,20);

這句話都做了些什麼事情?

1、因爲new用到了Person.class。所以會先找到person。class文件並加載到內存中。

2、執行該類中的static代碼塊,如果有的話,給person。class類進行初始化;

3、在堆內存中開闢空間,分配內存地址值;

4、在堆內存中建立對象的特有屬性,並進行默認初始化;

5、對屬性進行顯示初始化,

6、對對象進行構造代碼塊初始化;

7、對對象進行對性的構造函數初始化

8,將內存地址賦值給棧內存中的p變量。

 

 

方法區是優先於對象存在的,肯定是先於對象產生新的空間。

方法區是先加載了,相對於對象。堆內存裏的東西還沒有時,方法區就已經有內容了。優先於對象加載。

 

this是不可能用在靜態裏面的的。因爲靜態裏面的特性都是共享的。

 

先引用某功能,可以先對其建立對象。

 

調用方法和屬性,就先建立對象把他框進來這個思想。

 

//擴展知識——設計模式

         所謂模式,就是解決某一類問題最好最行之有效的方法。由老外四個人一共總結了java的23種通用模式。

         如果深入學習可以找些外文資料,或者找《設計模式》的書。

         不是偏代碼的,而是偏思想的,因此使用各種語言。

         把幾種模式綜合一下就稱之爲複雜的模式,我們稱之爲框架。

 

 

//單例設計模式:解決一個類中在內存只存在一個對象。

如某個程序的配置文件就是通過單例設計模式放在類當中的。

 

想要保證對象唯一

1、爲了避免其他程序過多建立該類對象,先禁止其他程序建立該類對象。

2、爲了讓其他程序可以訪問到該類對象,只好在本類中自定義一個對象;

3、爲了方便其他程序對自行定義對象的訪問,可以對外提供一些訪問方式。

 

這三部怎麼用代碼體現呢?

1、將構造函數私有化,

2、在類中創建一個本類 對象;

3、提供一個方法可以獲取到該對象。

 

總結:

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

 

單例設計模式有兩種方式:

先初始化對象叫做餓漢式;

single類一進內存,就已經創建好了對象。

 

對象是方法被調用時,才初始化,也叫做對象的延時加載,稱爲懶漢式。

single類進內存,對象還沒有存在,只有調用了getinstance方法時,才建立對象。

 

在實際開發中,一般都是用的餓漢式。因爲他安全,簡單。懶漢式會出現這方面的問題,因爲cpu在某一時刻點上只會處理同一個程序的。多任務同時進行的本質就是因爲cpu在幾千分之一秒之間切換,cpu中的切換是隨機的。可以用雙重判斷(多線程技術)來解決問題。

 

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

 

 

方法要被類訪問,就要先靜態。而且類中的成員變量先私有化一下。靜態的類可以直接被調用。表示共享。要想被調用只有兩種方法,第一就是對象,第二就是類。

 

對象是一定會在堆內存裏的。

 

 

 

先引用某功能,可以先對其建立對象。

 

調用方法和屬性,就先建立對象把他框進來這個思想。

 

 

 

 

 

 

 

 

        

         

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