一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

徐葳【2019版最新】40小時(shí)掌握J(rèn)ava語(yǔ)言之03面向?qū)ο?/span>

 大數(shù)據(jù)徐葳 2019-03-30

Java基礎(chǔ)之面向?qū)ο?/span>

第1章:面向?qū)ο蟾拍?/span>

下面就進(jìn)入java的核心部分:面向?qū)ο蟆?/span>

java是一門面向?qū)ο蟮恼Z(yǔ)言。

什么是面向?qū)ο竽兀?/span>

面向?qū)ο笫窍鄬?duì)于面向過(guò)程而言的。

1.1 理解面向?qū)ο?/span>

下面我們來(lái)舉個(gè)例子,

用手機(jī)發(fā)短信

1:開(kāi)機(jī)

2:發(fā)送短信

如果使用面向過(guò)程來(lái)實(shí)現(xiàn)這個(gè)過(guò)程的話就是第一步,打開(kāi)手機(jī),第二步發(fā)送短信,相當(dāng)于我們要針對(duì)手機(jī)定義兩個(gè)功能,一個(gè)是打開(kāi)手機(jī),一個(gè)是發(fā)送短信,這里強(qiáng)調(diào)的是執(zhí)行的過(guò)程。

如果使用面向?qū)ο蟮乃枷雭?lái)實(shí)現(xiàn)這個(gè)功能的話,就是我找到手機(jī),(手機(jī)本身是有開(kāi)機(jī)和發(fā)送短信的功能的),然后調(diào)用手機(jī)的開(kāi)機(jī)和發(fā)送短信功能即可,不需要我自己定義這兩個(gè)功能,強(qiáng)調(diào)的是具體事物,也稱為對(duì)象。

如圖1.1中的對(duì)比情況。

圖1.1 面向?qū)ο蠓治?/span>

也就是說(shuō)如果使用面向過(guò)程來(lái)實(shí)現(xiàn)這個(gè)功能,我們需要實(shí)現(xiàn)兩個(gè)功能,直接調(diào)用這兩個(gè)功能,

而使用面向?qū)ο笏枷氲脑?,我們就需要定義一個(gè)對(duì)象,把這兩個(gè)功能封裝到對(duì)象里面,后續(xù)使用的的話就只需要找到這個(gè)對(duì)象就行了,這個(gè)對(duì)象就有這些功能。

側(cè)重點(diǎn)是不一樣的。

面向過(guò)程的話我們需要關(guān)注這兩個(gè)過(guò)程具體是如何實(shí)現(xiàn)的,而面向?qū)ο蟮脑捨也恍枰芄δ軐?shí)現(xiàn)的細(xì)節(jié)就可以了,只需要會(huì)使用手機(jī)就行了。

面向?qū)ο笫窍雽?duì)于面向過(guò)程而言的,無(wú)論過(guò)程還是對(duì)象都是生活中的一種思考方式(思想)。

總結(jié):

1. 面向?qū)ο笫且环N符合現(xiàn)在人們思考習(xí)慣的一種思想。

2. 面向?qū)ο蟮某霈F(xiàn)讓角色發(fā)生了變化,從執(zhí)行者轉(zhuǎn)變成了指揮者。

3. 面向?qū)ο髮?fù)雜的事情簡(jiǎn)單化。

不在強(qiáng)調(diào)過(guò)程,而是強(qiáng)調(diào)對(duì)象,找到了對(duì)象,其實(shí)就找到了這些功能。

面向?qū)ο笃鋵?shí)就是基于面向過(guò)程而來(lái)的。

假設(shè)我想做幾道菜,但是我自己還不會(huì)做,

按照面向過(guò)程的思想,那么就需要我去學(xué)習(xí)這幾道菜的做法。

如果按照面向?qū)ο蟮乃枷?,我只需要找一個(gè)廚子就可以解決了。

或者我直接找一個(gè)會(huì)做飯的女朋友不是更好,什么洗衣服做飯都搞定了^^。

針對(duì)我們之前寫的數(shù)組排序的代碼來(lái)說(shuō),是我們自己實(shí)現(xiàn)的,按照我們剛才說(shuō)的,java是一門面向?qū)ο蟮恼Z(yǔ)言,那么他有沒(méi)有實(shí)現(xiàn)這個(gè)方法,并把這個(gè)方法封裝到一個(gè)對(duì)象中呢?

有!前面我們?cè)谥v數(shù)組排序的時(shí)候也講到過(guò)Arrays這個(gè)工具類,它里面有一個(gè)封裝好的sort排序方法,這其實(shí)就是面向?qū)ο笏枷氲囊环N具體體現(xiàn)。

1.2 面向?qū)ο蟮奶卣?/span>

面向?qū)ο蟮娜筇卣鳎?/span>

l 封裝(encapsulation)

l 繼承(inheritance)

l 多態(tài)(polymorphism)

后面會(huì)詳細(xì)分析面向?qū)ο蟮倪@三大特征。

2章:類與對(duì)象之間的關(guān)系

之前我們寫過(guò)一些類,還沒(méi)有定義過(guò)對(duì)象,那類與對(duì)象具體有什么關(guān)系呢?

2.1 類與對(duì)象的關(guān)系

計(jì)算機(jī)語(yǔ)言開(kāi)發(fā),其實(shí)就是不斷用計(jì)算機(jī)語(yǔ)言來(lái)描述現(xiàn)實(shí)生活中的事務(wù)。

對(duì)于java語(yǔ)言,它描述事物是通過(guò)類來(lái)體現(xiàn)的。

類:就是某一個(gè)具體事物的抽象,概念上的定義

對(duì)象:就是該類事物實(shí)實(shí)在在存在的個(gè)體

描述任意一類事物,其實(shí)就是在描述該類事物的屬性和行為。

我們把一批對(duì)象中共性的屬性和功能抽取出來(lái),定義為一個(gè)類,類就是這一組對(duì)象的抽象,如圖2.1所示。

圖 2.1 類與對(duì)象的關(guān)系

2.2 類與對(duì)象案例分析

現(xiàn)在有一個(gè)需求,使用計(jì)算機(jī)語(yǔ)言來(lái)描述汽車這一類事物。

代碼實(shí)例如圖2.2所示。

圖2.2 car代碼

如何創(chuàng)建該類的對(duì)象呢?

java中通過(guò)new關(guān)鍵字來(lái)創(chuàng)建實(shí)體,實(shí)體其實(shí)就是用來(lái)封裝具體數(shù)據(jù)用的,數(shù)組是這樣,對(duì)象也是。

Car c = new Car();//通過(guò)Car類創(chuàng)建了一個(gè)具體對(duì)象。該對(duì)象如何使用呢?為了方便使用該對(duì)象,就給對(duì)象起個(gè)名字。

等號(hào)左邊:定義了一個(gè)變量,是Car類型的。而Car是一個(gè)類,所以c是類類型變量,類類型變量一定指向?qū)ο?。因?yàn)樗硪粋€(gè)實(shí)體。

這樣我們就完成了一個(gè)對(duì)象的建立。

下面我們就想讓這個(gè)車運(yùn)行一下,車運(yùn)行的方法我們已經(jīng)封裝好了。直接調(diào)用run方法即可。

調(diào)用格式:對(duì)象.對(duì)象成員

c.run();//指揮車進(jìn)行運(yùn)行。

詳細(xì)代碼如圖2.3所示。

圖2.3 運(yùn)行car對(duì)象

最終輸出的color是null,num是0,因?yàn)檫@里我們還沒(méi)有給這些變量賦值,所以輸出的是默認(rèn)值。

從現(xiàn)實(shí)生活過(guò)渡到計(jì)算機(jī)中,

Car:對(duì)應(yīng)的是生活中的汽車圖紙

new Car():對(duì)應(yīng)的是生活中具體的汽車

2.3 對(duì)象的內(nèi)存圖

下面來(lái)看一下這段代碼在內(nèi)存中的到底是什么樣子的呢,如圖2.4所示。

Car c = new Car();

首先有棧和堆,在這我們先不說(shuō)方法,后面再說(shuō)

用new建立的都是實(shí)體,實(shí)體都是存在堆內(nèi)存中的,堆內(nèi)存會(huì)給這個(gè)實(shí)體分配一個(gè)內(nèi)存空間,分配內(nèi)存首地址值。

每個(gè)實(shí)體都有color和num屬性,如果沒(méi)有給這兩個(gè)屬性賦值,那這兩個(gè)屬性有沒(méi)有默認(rèn)值呢?

注意:堆內(nèi)存中的所有變量都有默認(rèn)初始化值,字符串默認(rèn)值為null,數(shù)字默認(rèn)值為0。

把內(nèi)存首地址賦給變量c,變量c就指向這個(gè)對(duì)象了。

c.color=”red”;

c.num=4;

c.run();

執(zhí)行代碼,就會(huì)打印紅色和四個(gè)輪胎。

圖2.4 對(duì)象內(nèi)存圖

第二個(gè)案例如圖2.5所示。

圖2.5 對(duì)象內(nèi)存圖

2.4 成員變量和局部變量

定義在類中的變量稱為成員變量,定義在函數(shù)中的變量稱為局部變量。

成員變量和局部變量的區(qū)別?

1. 作用范圍

成員變量:定義在類中,在整個(gè)類中都可以被訪問(wèn)

局部變量:只定義在局部范圍內(nèi),如:函數(shù)內(nèi),語(yǔ)句內(nèi)等,只在它所屬的局部大括號(hào)中有效

2. 存儲(chǔ)情況

成員變量:成員變量隨著對(duì)象的建立而建立,存在于對(duì)象所在的堆內(nèi)存中,當(dāng)對(duì)象編程垃圾被回收時(shí),該對(duì)象中的成員變量才會(huì)消失,所以,成員變量也稱為實(shí)例(對(duì)象)變量。

局部變量:局部變量存在于棧內(nèi)存中,當(dāng)方法或者語(yǔ)句被執(zhí)行的時(shí)候才存在,當(dāng)方法或者語(yǔ)句執(zhí)行結(jié)束時(shí),該局部變量會(huì)被自動(dòng)釋放

3. 初始化情況

成員變量:在堆內(nèi)存中有默認(rèn)初始化值

局部變量:沒(méi)有默認(rèn)初始化值,需要手工初始化后才可以使用

2.5 匿名對(duì)象

這塊內(nèi)容了解就可以。

下面是正常的代碼,如圖2.6所示。


圖2.6 代碼

注意:下面的代碼是完全不同的,第一個(gè)寫法只創(chuàng)建了一個(gè)對(duì)象,第二種寫法創(chuàng)建了三個(gè)對(duì)象,這種寫法就是匿名對(duì)象的寫法,如圖2.7所示。

圖2.7 匿名對(duì)象

為什么使用匿名對(duì)象的時(shí)候可以調(diào)用方法,但是不建議調(diào)用屬性呢?

因?yàn)槟涿麑?duì)象調(diào)用屬性沒(méi)意義。

如圖2.8所示。

默認(rèn)car里面有兩個(gè)屬性,顏色為紅色,num為4.

左邊的代碼會(huì)產(chǎn)生一個(gè)對(duì)象。并修改顏色和num

右邊的代碼會(huì)產(chǎn)生三個(gè)對(duì)象,但是在棧里面沒(méi)有任何東西,因?yàn)?,就沒(méi)有變量產(chǎn)生,直接產(chǎn)生對(duì)象,當(dāng)產(chǎn)生一個(gè)對(duì)象,并修改對(duì)象中的一個(gè)屬性之后,這個(gè)對(duì)象就變成垃圾了,這個(gè)對(duì)象什么事也沒(méi)干。最后執(zhí)行run的時(shí)候打印出來(lái)的還是默認(rèn)屬性的值。

圖2.8 匿名對(duì)象的調(diào)用


匿名對(duì)象還可以作為實(shí)際參數(shù)進(jìn)行傳遞

如果new多個(gè)car,都修改統(tǒng)一的屬性,調(diào)用同樣的方法,這樣代碼重復(fù)度太高,可以提取一個(gè)方法,把car對(duì)象作為一個(gè)參數(shù)進(jìn)行傳遞,如圖2.9所示。

圖2.9 匿名對(duì)象的第二種用法

匿名對(duì)象:沒(méi)有名字的對(duì)象,是定義對(duì)象的一種簡(jiǎn)化形式。

使用注意:

l 當(dāng)對(duì)象對(duì)方法只進(jìn)行一次調(diào)用的時(shí)候,可以使用匿名對(duì)象對(duì)代碼進(jìn)行簡(jiǎn)化。

l 如果對(duì)象要對(duì)成員進(jìn)行多次調(diào)用,必須給對(duì)象起個(gè)名字,不能再使用匿名對(duì)象

3章:封裝

下面我們來(lái)學(xué)習(xí)一下面向?qū)ο蟮牡谝粋€(gè)特征:封裝。

3.1 封裝介紹

封裝:是指隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外提供公共訪問(wèn)方式。

舉個(gè)例子,人開(kāi)車這個(gè)例子,

我們想要開(kāi)車的話,沒(méi)必要知道具體車是怎么運(yùn)行的,我們只要用鑰匙把車啟動(dòng)就可以了。

拿我們計(jì)算機(jī)來(lái)說(shuō),我們的筆記本。里面都有主板,內(nèi)存,硬盤,具體這些東西是怎么運(yùn)行的不需要我們關(guān)心,這些細(xì)節(jié)都被封裝到計(jì)算機(jī)里面了,計(jì)算機(jī)給我們提供了一個(gè)開(kāi)機(jī)按鈕,我們只需要按一下開(kāi)機(jī)按鈕就可以使用這些東西了。

封裝的好處:

l 將變化隔離。

具體計(jì)算機(jī)內(nèi)部有什么變化我們不需要知道,只要能正常開(kāi)機(jī)使用即可。

l 便于使用。

我們不需要知道計(jì)算機(jī)內(nèi)部是怎么拼裝的,只要能使用就可以。

l 提高重用性。

即使后期筆記本的主板或者內(nèi)存發(fā)生變化,筆記本還是可以繼續(xù)使用的。

l 提高安全性。

如果把主板,內(nèi)存,硬盤,全部暴露在外面的話,是很不安全的

封裝原則:

l 將不需要對(duì)外提供的內(nèi)容都隱藏起來(lái)。

l 把屬性都隱藏,提供公共方法對(duì)其訪問(wèn)。

3.2 private(私有)

如圖3.1所示:

執(zhí)行main函數(shù),會(huì)打印出人的年齡,如果把年齡定義為20,則沒(méi)有問(wèn)題,如果定義為-20,則就有問(wèn)題了,雖然代碼可以運(yùn)行,但是不合常理,人的年齡不可能有負(fù)數(shù),但是在java中int類型是可以接受負(fù)數(shù)的。所以說(shuō)直接把a(bǔ)ge這個(gè)變量暴露出去,讓其他人操作是比較危險(xiǎn)的,這個(gè)時(shí)候就需要把這個(gè)age這個(gè)變量隱藏起來(lái),不想讓其他人直接訪問(wèn)進(jìn)行賦值。

圖3.1 代碼

在這為了不讓其他人訪問(wèn),我們需要介紹一個(gè)權(quán)限修飾符:private

private是私有的意思。

當(dāng)我們?cè)赼ge 前面加一個(gè)private之后,再編譯PersonDemo類的代碼,會(huì)報(bào)錯(cuò),提示age這個(gè)屬性只能在person類中訪問(wèn)。

這是因?yàn)槲覀儼阉揎棡樗接械闹螅荒茉谒鶎賹?duì)象中使用,權(quán)限降低了。其他程序就不能訪問(wèn)了。這樣就保證了安全性了。

但是外界就無(wú)法操作了,該如何賦值呢?

那么我們可以在所屬對(duì)象中提供一個(gè)方法,在這先隨便起個(gè)名字haha(),我在這個(gè)類的方法中是可以操作這個(gè)屬性的,你只需要訪問(wèn)我這個(gè)方法就可以了。

這個(gè)時(shí)候如果你傳遞的值為負(fù)數(shù)的話,我就可以在函數(shù)中使用if進(jìn)行判斷了。這樣我們就可以通過(guò)對(duì)外提供公有方法的形式對(duì)外提供訪問(wèn),并對(duì)訪問(wèn)進(jìn)行控制,如圖3.2所示。

圖3.2 代碼

通常將成員變量私有化,并通過(guò)對(duì)外提供set 和 get方法對(duì)其進(jìn)行設(shè)置和獲取。

方法名稱的定義格式,第一個(gè)單詞首字母小寫,后面的單詞首字母大寫

一般情況下,一個(gè)類中只要有屬性,這個(gè)屬性都會(huì)私有,并且對(duì)外提供兩個(gè)方法,一個(gè)set和一個(gè)get,這都是固定的格式。

set方法是對(duì)私有的變量進(jìn)行賦值操作的

get方法是獲取私有變量的值的。

set方法的返回值一般都是void類型,他只負(fù)責(zé)賦值。

get方法的返回值類型一般都是私有變量的類型。

代碼實(shí)現(xiàn)如圖3.3所示。

圖3.3 代碼

也就是說(shuō)私有就是封裝的一種體現(xiàn)形式。

這里我們是對(duì)成員變量進(jìn)行私有化,那么成員方法需不需要私有化呢?

這個(gè)就要看需求了,如果確實(shí)不需要對(duì)外提供訪問(wèn),那么就設(shè)置為私有的。

Eclipse 中提供了一個(gè)根據(jù)成員變量快速生成 get/set 方法的工具。主菜單【Source】→【Generate Getters Setters】。如圖3.4所示。

圖3.4 快速生成get和set方法

4章:構(gòu)造函數(shù)

下面我們來(lái)學(xué)習(xí)一下類里面的構(gòu)造函數(shù)

這個(gè)函數(shù)和我們之前學(xué)過(guò)的函數(shù)不一樣,我們之前學(xué)過(guò)兩種,主函數(shù)和一般函數(shù)

4.1 構(gòu)造函數(shù)介紹

構(gòu)造函數(shù)的特點(diǎn):

l 函數(shù)名與類名相同

l 不用定義返回值類型

l 不需要寫return語(yǔ)句(沒(méi)有具體的返回值)

l 在對(duì)象建立的時(shí)候被直接調(diào)用

一般的函數(shù),我們想要使用的時(shí)候,必須指定才能調(diào)用,而構(gòu)造函數(shù)則比較特殊,不需要指定。當(dāng)類初始化的時(shí)候就會(huì)自動(dòng)被調(diào)用,如圖4.1所示。

圖4.1 構(gòu)造函數(shù)代碼

注意:

構(gòu)造函數(shù)再對(duì)象建立時(shí)就被直接調(diào)用

構(gòu)造函數(shù)的作用:

用于給對(duì)象進(jìn)行初始化。

前面我們?cè)趧?chuàng)建類的時(shí)候沒(méi)有創(chuàng)建構(gòu)造函數(shù)。那對(duì)象有沒(méi)有被初始化呢?

被初始化了,如果我們沒(méi)有顯式創(chuàng)建構(gòu)造函數(shù),那么系統(tǒng)會(huì)給這個(gè)類創(chuàng)建一個(gè)默認(rèn)的構(gòu)造函數(shù),例如前面創(chuàng)建的Person類,如圖4.2所示。

圖4.2 默認(rèn)構(gòu)造函數(shù)

注意:

當(dāng)類中沒(méi)有定義構(gòu)造函數(shù)時(shí),系統(tǒng)會(huì)自動(dòng)給該類加上一個(gè)空參數(shù)的構(gòu)造函數(shù),這個(gè)是類中默認(rèn)的構(gòu)造函數(shù)。

當(dāng)類中自定義了構(gòu)造函數(shù),這時(shí)默認(rèn)的構(gòu)造函數(shù)就沒(méi)有了。

在一個(gè)類中可以定義多個(gè)構(gòu)造函數(shù),以進(jìn)行不同的初始化,多個(gè)構(gòu)造函數(shù)存在于類中,是以重載的形式體現(xiàn)的,因?yàn)闃?gòu)造函數(shù)的名稱都相同。

如圖4.3中的案例所示。

這兩個(gè)構(gòu)造函數(shù)都可以使用,初始化方式是不一樣的。

默認(rèn) new person2();是調(diào)用person2()這個(gè)構(gòu)造函數(shù)

有些人一出生就帶著姓名new person2(“zhangsan”);這時(shí)就會(huì)使用person2(String n)這個(gè)構(gòu)造函數(shù)進(jìn)行初始化。

圖 4.3 多個(gè)構(gòu)造函數(shù)

4.2 構(gòu)造函數(shù)和一般函數(shù)的區(qū)別

構(gòu)造函數(shù)和一般函數(shù)的區(qū)別:

l 區(qū)別之一

一般函數(shù)是用于定義對(duì)象應(yīng)該具備的功能

構(gòu)造函數(shù)定義的是對(duì)象在建立時(shí)需要具備的一些內(nèi)容,也就是對(duì)象的初始化內(nèi)容

l 區(qū)別之二

一般函數(shù)在對(duì)象建立后,當(dāng)對(duì)象調(diào)用該功能時(shí)才會(huì)執(zhí)行。

構(gòu)造函數(shù)是在對(duì)象建立時(shí)被調(diào)用,為了給對(duì)象進(jìn)行初始化。

4.3 構(gòu)造函數(shù)練習(xí)題

需求:

創(chuàng)建一個(gè)Person類,Person有姓名、年齡(年齡在1~100之間)屬性,還有一個(gè)說(shuō)話的功能,在說(shuō)話的時(shí)候會(huì)把自己的姓名和年齡說(shuō)出來(lái)。

在創(chuàng)建Person對(duì)象的時(shí)候要支持直接傳遞姓名和年齡參數(shù)。

代碼實(shí)現(xiàn)如圖4.4所示。

圖4.4 練習(xí)題

5章:this關(guān)鍵字

5.1 this關(guān)鍵字介紹

我們先寫一個(gè)demo,正常情況下可以這樣寫,如圖5.1所示。

這個(gè)代碼雖然沒(méi)問(wèn)題,但是參數(shù)的名稱定義的不太友好,不容易識(shí)別。我們想要定義一個(gè)有意義的名稱,這樣別人在調(diào)用這個(gè)構(gòu)造函數(shù)的時(shí)候就知道該傳遞什么內(nèi)容。

圖5.1 代碼

這樣定義行不行呢?如圖5.2所示。結(jié)果發(fā)現(xiàn)打印的結(jié)果為空

圖5.2 代碼

注意:當(dāng)你的局部變量和成員變量同名的時(shí)候,因?yàn)楹瘮?shù)內(nèi)部已經(jīng)有這個(gè)局部變量了,那么就不會(huì)再到外面找了,所以在這就是局部變量name把值賦給了自己。所以成員變量name的值還是null。

如果想把這個(gè)局部變量賦給成員變量怎么辦呢?

在這可以使用this關(guān)鍵字

當(dāng)局部變量和成員變量重名時(shí),可以使用this這個(gè)關(guān)鍵字進(jìn)行區(qū)分,如圖5.3所示。

圖5.3 代碼

原理是什么呢?

this:代表所在函數(shù)所屬對(duì)象的引用。

因?yàn)閠his是在person4這個(gè)構(gòu)造函數(shù)中,這個(gè)函數(shù)是屬于p這個(gè)對(duì)象的,所以,this就代表p的引用。

也就是說(shuō),this代表當(dāng)前對(duì)象。

5.2 this關(guān)鍵字在構(gòu)造函數(shù)間的調(diào)用

如果想要在初始化一個(gè)對(duì)象的時(shí)候,還進(jìn)行其他初始化,那就需要用到構(gòu)造函數(shù)之間的調(diào)用了

假設(shè)在初始化姓名之后,還想初始化年齡,不能new兩個(gè)Person,這樣就是兩個(gè)對(duì)象了,所以就需要在初始化名字的構(gòu)造函數(shù)中調(diào)用初始化年齡的方法。

注意:不能在初始化姓名的構(gòu)造函數(shù)中使用this.Person(20),這樣是不行的,這個(gè)Person不是一個(gè)普通的方法。

應(yīng)該直接使用this(20),這樣就表示初始化過(guò)姓名的時(shí)候,先調(diào)用初始化年齡的構(gòu)造函數(shù)進(jìn)行初始化,再執(zhí)行this.name=name進(jìn)行姓名初始化,如圖5.4所示。

圖5.4 構(gòu)造函數(shù)的調(diào)用

其實(shí)可以在這簡(jiǎn)單記住一句話,想要實(shí)現(xiàn)構(gòu)造函數(shù)之間的調(diào)用,需要使用this關(guān)鍵字。

注意:this語(yǔ)句只能定義在構(gòu)造函數(shù)的第一行,因?yàn)槌跏蓟瘎?dòng)作必須先完成,如果this語(yǔ)句不放在構(gòu)造函數(shù)的第一行,是會(huì)報(bào)錯(cuò)的。

下面這種寫法是錯(cuò)誤的,如圖5.5所示。

圖5.5構(gòu)造函數(shù)的調(diào)用

也就是說(shuō)在構(gòu)造函數(shù)中是不可以寫兩個(gè)this語(yǔ)句的,因?yàn)榈诙€(gè)this語(yǔ)句就在第二行了,如圖5.6所示。

圖5.6 構(gòu)造函數(shù)的調(diào)用

下面這種寫法也不行,因?yàn)榉痔?hào)就表示第一個(gè)語(yǔ)句的結(jié)束,如圖5.7所示。

圖5.7 構(gòu)造函數(shù)的調(diào)用

6章:static關(guān)鍵字

6.1 static關(guān)鍵字介紹

static這個(gè)關(guān)鍵字我們已經(jīng)用了很長(zhǎng)時(shí)間了。

static關(guān)鍵字:主要用于修飾成員(成員變量和成員函數(shù))

看圖6.1所示的例子。

如果我new多個(gè)person,在內(nèi)存中就會(huì)存在多個(gè)對(duì)象,并且這些對(duì)象還有一些特點(diǎn),country都一樣,如果都是中國(guó)人的話,那么所有的country字段的值都為cn,所有的對(duì)象中都需要存儲(chǔ)這個(gè)相同的值,這樣是會(huì)造成重復(fù)數(shù)據(jù),浪費(fèi)內(nèi)存空間。

圖6.1 代碼

此時(shí)我可以把這個(gè)country定義到外面,對(duì)象如果想要使用的話都從外面取就行了,這樣就需要在country前面加上一個(gè)修飾符,static,這樣,加上靜態(tài)之后,這個(gè)country就不會(huì)在堆內(nèi)存的每個(gè)對(duì)象內(nèi)存在了,而是在堆內(nèi)存以外的位置存在,被所有對(duì)象所共享,如圖6.2所示。

這就是靜態(tài)的特點(diǎn)。

圖6.3 靜態(tài)

注意:靜態(tài)中的數(shù)據(jù)不存放在堆內(nèi)存中。

靜態(tài)成員多了一種調(diào)用方式,可以直接被類名所調(diào)用。

那是不是可以對(duì)類中所有的屬性都使用靜態(tài)這種功能呢?

可以是可以,語(yǔ)法沒(méi)有問(wèn)題,但是會(huì)有其它問(wèn)題,

name本身是對(duì)象當(dāng)中的數(shù)據(jù),每個(gè)人的姓名是不一樣的,如果使用static關(guān)鍵字定義的話,只需要定義一次值,所有對(duì)象的name都是一個(gè)值,這樣就不合理了。

針對(duì)對(duì)象共有的數(shù)據(jù),可以使用static關(guān)鍵字定義,針對(duì)對(duì)象特有的數(shù)據(jù),就不能使用static了,這就是static關(guān)鍵字應(yīng)用的場(chǎng)景。

將共享的數(shù)據(jù)提取出來(lái),靜態(tài)化,將非共享的數(shù)據(jù)存儲(chǔ)到對(duì)象中。

舉個(gè)例子

在公司里面,飲水機(jī)一般只有一個(gè),所有人都到這接水喝,如果每個(gè)人都分配一臺(tái)飲水機(jī)可以嗎?也是可以的,但是這樣就太浪費(fèi)空間了,所以就把飲水機(jī)提取出來(lái),所有人都使用這一個(gè)就可以了,這就是共享數(shù)據(jù),但是接水的杯子是每個(gè)人都有一個(gè)的。

被靜態(tài)修飾后的成員具備以下特點(diǎn):

l 隨著類的加載而加載

l 優(yōu)先于對(duì)象存在

l 被所有對(duì)象所共享

l 可以直接被類名調(diào)用(也可以被對(duì)象調(diào)用。)

看下面圖6.4所示代碼。

圖6.4 代碼

靜態(tài)方法只能訪問(wèn)靜態(tài)成員,如圖6.5中,這樣編譯是會(huì)報(bào)錯(cuò)的

因?yàn)殪o態(tài)優(yōu)先于對(duì)象存在,當(dāng)show方法存在的時(shí)候,name還不在呢,所以調(diào)用是會(huì)報(bào)錯(cuò)的。

圖6.5 靜態(tài)調(diào)用

主函數(shù)也是靜態(tài)的,這個(gè)具體在后面進(jìn)行分析。

static(靜態(tài))使用注意事項(xiàng):

l 靜態(tài)方法只能訪問(wèn)靜態(tài)成員

l 靜態(tài)方法中不可以寫this,super關(guān)鍵字

l 主函數(shù)是靜態(tài)的

l 靜態(tài)關(guān)鍵字不能修飾局部變量

靜態(tài)的好處:靜態(tài)成員多了一種調(diào)用方式,可以直接被類名調(diào)用。也可以被對(duì)象調(diào)用

靜態(tài)的弊端:靜態(tài)方法只能訪問(wèn)靜態(tài)成員,出現(xiàn)了訪問(wèn)局限性

6.2靜態(tài)變量和實(shí)例變量的區(qū)別

靜態(tài)變量和實(shí)例變量的區(qū)別

1

靜態(tài)變量也稱為類變量,可以直接被類名調(diào)用,所屬于類。

非靜態(tài)變量稱為成員變量,或者實(shí)例變量,是被對(duì)象調(diào)用,所屬于對(duì)象

2

靜態(tài)變量隨著類的加載而加載,也意味著隨著類的消失而消失,生命周期最長(zhǎng)。

實(shí)例變量,隨著對(duì)象的創(chuàng)建而加載,隨著對(duì)象的消失而消失,按照對(duì)象的生命周期而存在。

3

靜態(tài)變量存儲(chǔ)在方法區(qū)的靜態(tài)區(qū)中。

實(shí)例變量存在于對(duì)象所屬的堆內(nèi)存中

4

靜態(tài)變量數(shù)據(jù),被所有對(duì)象所共享。

實(shí)例變量是對(duì)象中的特有數(shù)據(jù)。

6.3 靜態(tài)的使用場(chǎng)景

什么時(shí)候使用static呢?

l 成員變量:

當(dāng)該成員變量所存儲(chǔ)的數(shù)據(jù),每一個(gè)對(duì)象都是一樣的,這時(shí)就沒(méi)有必要吧該數(shù)據(jù)存儲(chǔ)到每一個(gè)對(duì)象中,只要讓所有對(duì)象共享該數(shù)據(jù)即可,這時(shí)成員就需要被static修飾。

l 成員函數(shù)

當(dāng)成員函數(shù)內(nèi)并沒(méi)有訪問(wèn)對(duì)象中的特有數(shù)據(jù)時(shí),就可以將該方法定義成靜態(tài)的。

簡(jiǎn)單說(shuō):該函數(shù)如果訪問(wèn)了成員變量,該函數(shù)就是非靜態(tài)的。

該函數(shù)沒(méi)有訪問(wèn)過(guò)成員變量,或者訪問(wèn)過(guò)靜態(tài)的成員變量,那么為了程序的嚴(yán)謹(jǐn)性,將該方法定義成靜態(tài)的,因?yàn)樵摲椒ú恍枰獙?duì)象存在就可以使用。

6.4 工具類的應(yīng)用

假設(shè)要做一個(gè)數(shù)組排序,并打印,代碼實(shí)現(xiàn)如圖6.6所示。

圖6.6 數(shù)組排序打印

前面實(shí)現(xiàn)的功能代碼沒(méi)有問(wèn)題,但是所有代碼都放在主函數(shù)內(nèi)導(dǎo)致代碼很臃腫,并且后期如果還想使用排序功能的話也不能實(shí)現(xiàn)代碼的復(fù)用。

所以需要對(duì)代碼進(jìn)行重構(gòu),抽取兩個(gè)方法,排序方法和數(shù)組轉(zhuǎn)化為string的方法,代碼實(shí)現(xiàn)如圖6.7所示。

圖6.7 抽取方法

剛才我們提取的功能現(xiàn)在只能在這個(gè)類中才能使用,我們希望以后能隨時(shí)使用這個(gè)功能,所以我們現(xiàn)在還需要把這些功能封裝到一個(gè)數(shù)組工具類中,以后想對(duì)數(shù)組操作的時(shí)候,只要找到這個(gè)對(duì)象,就可以對(duì)數(shù)組進(jìn)行操作了。

把剛才提取的兩個(gè)方法,重新封裝到一個(gè)ArrayTool類中,這個(gè)里面是不需要主函數(shù)的,因?yàn)閷懼骱瘮?shù)主要是為了讓當(dāng)前類執(zhí)行。

注意:先把這兩個(gè)方法上的static關(guān)鍵字去掉。

這個(gè)類定義好了之后,任何人都可以使用里面的功能了,如圖6.8所示。

圖6.8 提取公共方法

這樣再進(jìn)行排序的時(shí)候就可以這樣使用了,如圖6.9所示。

圖6.9 使用工具類

下面分析下這個(gè)Arraytool類

這個(gè)類如果我們多個(gè)地方使用的時(shí)候是需要new多次的,會(huì)生成多個(gè)對(duì)象,然后分析這個(gè)類里面的方法,發(fā)現(xiàn)這里面的方法并沒(méi)有訪問(wèn)這個(gè)類的特有成員變量,那么這個(gè)時(shí)候,這個(gè)對(duì)象的建立是沒(méi)有意義的。

其實(shí)對(duì)象存在的根本原因是為了封裝他的特有數(shù)據(jù),在這個(gè)類里面沒(méi)有特有數(shù)據(jù),所以這幾個(gè)方法都可以使用static進(jìn)行修飾。

下面把這個(gè)工具類里面的所有方法都加上static關(guān)鍵字,那么再使用這個(gè)工具類的時(shí)候就非常簡(jiǎn)單了,使用的時(shí)候直接使用類名調(diào)用即可,如圖6.10所示。

圖6.10 工具類的使用

這個(gè)類中的功能都被靜態(tài)化后,只需要使用類名調(diào)用即可,但是其他程序在使用該類時(shí),是可以建立該類對(duì)象的(因?yàn)樵擃愔杏幸粋€(gè)默認(rèn)的構(gòu)造函數(shù))。

但是該類并不需要對(duì)象就可以使用類中的成員,所以針對(duì)這個(gè)類建立對(duì)象是沒(méi)有意義的,為了提高程序的嚴(yán)謹(jǐn)性,應(yīng)該強(qiáng)制不讓其他程序建立該類對(duì)象。

如何才能讓其他程序訪問(wèn)不到我的構(gòu)造函數(shù)呢(也就是說(shuō)如何才能強(qiáng)制不讓其他程序建立該類對(duì)象)?

私有化構(gòu)造函數(shù)就可以,如圖6.11所示。

圖6.11 私有化構(gòu)造函數(shù)

下面再給這個(gè)類加一些注釋,不然把這個(gè)工具類給其他人的時(shí)候他們不知道該如何使用。

完整工具類代碼示例如圖6.12所示。

圖6.12 工具類案例

6.5 main函數(shù)

上一節(jié)我們?cè)趯W(xué)習(xí)靜態(tài)的時(shí)候說(shuō),主函數(shù)是靜態(tài)的,為什么把它單獨(dú)列出來(lái)呢?

因?yàn)橹骱瘮?shù)比較特殊,他是被虛擬機(jī)所調(diào)用的。

這個(gè)例子編譯會(huì)報(bào)錯(cuò),因?yàn)閟how不是靜態(tài)的,在main中無(wú)法直接調(diào)用,如圖6.13所示。

圖6.13 代碼

那這個(gè)加上靜態(tài)之后還是不行,因?yàn)閤不是靜態(tài)的,如圖6.14所示,

圖6.14 代碼

如果想讓代碼編譯不報(bào)錯(cuò),還需要把x定義為靜態(tài),但是這樣就導(dǎo)致方法和變量的生命周期變長(zhǎng),這樣是沒(méi)有意義的,我只是為了簡(jiǎn)單的打印一個(gè)x而已。

所以不能這樣做,把static取消掉,show這個(gè)時(shí)候是非靜態(tài)的,只能被對(duì)象調(diào)用。

那在main函數(shù)中能不能使用this來(lái)調(diào)用show方法?

注意了,靜態(tài)里面是不能使用this的。

所以只能使用new創(chuàng)建一個(gè)對(duì)象來(lái)調(diào)用show方法。

這個(gè)類存在的目的就是去建立其他類的對(duì)象,并調(diào)用其他類中的功能。

可以驗(yàn)證其他類中的功能是否可用。(也包含當(dāng)前類。)

下面來(lái)解釋下主函數(shù)的定義:

注意:主函數(shù)沒(méi)有返回值,假設(shè)有返回值,虛擬機(jī)也不知道該怎么用。

public static void main(String[] args)

public:jvm調(diào)用的函數(shù)必須權(quán)限足夠大,所以被public修飾

static:主函數(shù)隨著類的加載而加載,jvm不需要?jiǎng)?chuàng)建該類對(duì)象就可以完成對(duì)該函數(shù)的調(diào)用,所以是靜態(tài)的

void:主函數(shù)沒(méi)有返回值

main:函數(shù)名,是固定的,jvm可以識(shí)別

(String[] args):主函數(shù)的參數(shù)列表。參數(shù)類型是:一個(gè)字符串?dāng)?shù)組類型的參數(shù)。

args:參數(shù)名稱,這個(gè)名稱可以隨便改,全稱是arguments

主函數(shù)有參數(shù),那么jvm調(diào)用的時(shí)候到底傳入了什么?

先打印這個(gè)args參數(shù),發(fā)現(xiàn)打印的結(jié)果是一個(gè)字符串?dāng)?shù)組。

再打印一下數(shù)數(shù)組的長(zhǎng)度,發(fā)現(xiàn)是0。

這也就說(shuō)明默認(rèn)情況下jvm在調(diào)用main方法的時(shí)候什么參數(shù)都沒(méi)有傳遞。

如圖6.15所示。

圖6.15 args參數(shù)

如何給main方法傳遞參數(shù)呢?

在執(zhí)行這個(gè)類的時(shí)候 ,在后面指定參數(shù)即可,這些參數(shù)會(huì)被jvm封裝到一個(gè)字符串?dāng)?shù)組傳遞到類的主函數(shù)中。

這樣就可以讓用戶在運(yùn)行程序的時(shí)候,動(dòng)態(tài)傳入指定的參數(shù),在eclipse中可以這樣來(lái)實(shí)現(xiàn)。

代碼如圖6.16所示,這個(gè)代碼默認(rèn)情況下直接運(yùn)行是會(huì)報(bào)錯(cuò)的,數(shù)組角標(biāo)越界異常。

eclipse中執(zhí)行流程如圖6.17所示。

圖6.16 代碼

圖6.17 執(zhí)行流程

運(yùn)行結(jié)果如圖6.18所示。

圖6.18 結(jié)果

注意:如果想要傳遞多個(gè)參數(shù),則在這里寫多個(gè)參數(shù)即可,多個(gè)參數(shù)之間用空格隔開(kāi),如圖6.19所示。

圖6.19 傳遞多個(gè)參數(shù)。

使用for循環(huán)把a(bǔ)rgs中的參數(shù)都打印一下,如圖6.20所示。

圖6.20 打印main接收到的參數(shù)

6.6 靜態(tài)代碼塊

接下來(lái)學(xué)習(xí)一下靜態(tài)中的靜態(tài)代碼塊。

靜態(tài)代碼塊的格式:

static{

code...;

}

例子:

如果一個(gè)類里面的所有成員都是靜態(tài)的,也把構(gòu)造函數(shù)私有化了,不能創(chuàng)建對(duì)象了,這個(gè)時(shí)候還想給這個(gè)類進(jìn)行一些初始化動(dòng)作。

在這我們就可以使用靜態(tài)代碼塊來(lái)實(shí)現(xiàn)。

靜態(tài)代碼塊的作用:

當(dāng)類在加載進(jìn)內(nèi)存時(shí),如果需要進(jìn)行一些內(nèi)容的執(zhí)行,完成一個(gè)類的初始化,就需要使用靜態(tài)代碼塊來(lái)完成

靜態(tài)代碼塊的特點(diǎn):

當(dāng)類被加載時(shí),靜態(tài)代碼就執(zhí)行了,而且只執(zhí)行一次,優(yōu)先于main函數(shù)執(zhí)行。

看下這個(gè)代碼的執(zhí)行結(jié)果,如圖6.21所示。

從這個(gè)代碼的輸出結(jié)果中可以看出來(lái),靜態(tài)代碼只會(huì)執(zhí)行一次,并且會(huì)優(yōu)先于main函數(shù)執(zhí)行。

圖6.21 靜態(tài)代碼塊的執(zhí)行順序

7章:?jiǎn)卫O(shè)計(jì)模式

下面使用靜態(tài)代碼塊的知識(shí)來(lái)學(xué)習(xí)一下設(shè)計(jì)模式

設(shè)計(jì)模式:可以理解為是一個(gè)固定的流程,就像是工廠里面的流水線,假設(shè)要做一個(gè)手機(jī),都是有步驟的,先做什么,再做什么。都按照這個(gè)流程來(lái)走,就可以提高工作的效率。

設(shè)計(jì)模式:就是解決某類問(wèn)題最行之有效的解決方案,設(shè)計(jì)模式是一種思想。

Java里面也有設(shè)計(jì)模式,一共總結(jié)出了23種設(shè)計(jì)模式

在這我們先學(xué)習(xí)其中的一種模式:?jiǎn)卫O(shè)計(jì)模式

7.1 單例設(shè)計(jì)模式介紹

單例設(shè)計(jì)模式

解決的問(wèn)題:保證一個(gè)類在內(nèi)存中只有一個(gè)對(duì)象

簡(jiǎn)單說(shuō)就是保證一個(gè)類在內(nèi)存中的對(duì)象唯一性

應(yīng)用場(chǎng)景:

比如配置文件,A程序要使用配置文件對(duì)象,B程序也要使用配置文件對(duì)象,希望A程序?qū)ε渲梦募?shù)據(jù)修改后,B程序可以直接使用,那么就需要A程序和B程序使用同一個(gè)對(duì)象

看下面這個(gè)圖7.1。假設(shè)我有一個(gè)類,這個(gè)類里面封裝了很多配置信息, 右邊有兩個(gè)程序A和B 都要使用這個(gè)配置里面的信息,首先是A程序,使用這個(gè)類的時(shí)候需要使用new創(chuàng)建這個(gè)對(duì)象,后續(xù)可能會(huì)修改這個(gè)配置中某一些屬性的值。

后面B程序也要使用這個(gè)配置類,也需要重新new,可能也會(huì)修改配置類中屬性的值。

這個(gè)時(shí)候兩個(gè)程序中的修改操作都是修改自己創(chuàng)建的config配置對(duì)象,這是兩個(gè)單獨(dú)的對(duì)象,這樣就不能實(shí)現(xiàn)使用共同的配置了。

這個(gè)時(shí)候我們希望A程序和B程序修改的都是同一個(gè)對(duì)象。

那我們把這個(gè)類中的屬性都定義成靜態(tài)不是就可以嗎

注意:定義靜態(tài)理論上是可以的,但是這個(gè)配置類里面有很多配置信息,如果都定義成靜態(tài)的話,造成生命周期過(guò)長(zhǎng)。但是我們還是希望A程序和B程序使用到的是同一個(gè)對(duì)象,那么就需要保證這個(gè)類在內(nèi)存中的對(duì)象唯一性。

圖7.1 配置信息

如何保證一個(gè)類在內(nèi)存中的對(duì)象唯一性呢?

1:在本類中自定義一個(gè)本類對(duì)象

2:對(duì)外提供獲取該對(duì)象的方式即可

代碼具體體現(xiàn)

1:私有化構(gòu)造函數(shù)

2:創(chuàng)建一個(gè)私有并且靜態(tài)的本類的對(duì)象

3:創(chuàng)建一個(gè)公共的static方法返回該對(duì)象

7.2 單例設(shè)計(jì)模式的兩種實(shí)現(xiàn)

第一種實(shí)現(xiàn):

代碼實(shí)現(xiàn)如圖7.2所示。

圖7.2 單例

驗(yàn)證一下,如果結(jié)果為true,就說(shuō)明是一個(gè)對(duì)象,如圖7.3所示。

圖7.3 單例

單例模式第二種實(shí)現(xiàn)形式

這種方式是對(duì)象的延遲加載方式

前面寫的直接new的方式是類一加載,這個(gè)對(duì)象就進(jìn)內(nèi)存了,而第二種實(shí)現(xiàn)方式只有在調(diào)用getInstance的時(shí)候才會(huì)創(chuàng)建對(duì)象。也就是什么時(shí)候使用,什么時(shí)候創(chuàng)建。

這一種對(duì)內(nèi)存空間的利用還是比較好的。

不過(guò)一般我們使用單例的時(shí)候,肯定是要使用這個(gè)對(duì)象,晚一點(diǎn)加載對(duì)我們來(lái)說(shuō),其實(shí)意義不是很大。

所以在工作中還是第一種用的比較多。

第二種雖然看起來(lái)比較好,但是會(huì)存在一些問(wèn)題,如果在多線程并發(fā)訪問(wèn)的時(shí)候會(huì)有一些安全隱患。這個(gè)等后面講到多線程的時(shí)候再詳細(xì)解釋。

開(kāi)發(fā)用第一種,面試用第二種。

第二種實(shí)現(xiàn)如圖7.4所示。

圖7.4 第二種單例實(shí)現(xiàn)

為了區(qū)分這兩種方式。

前面學(xué)習(xí)的第一種方式是餓漢式。//這個(gè)家伙比較餓,一加載就創(chuàng)建,吃掉。

第二種稱為懶漢式。//這家伙比較懶,什么時(shí)候用,什么時(shí)候再創(chuàng)建。

一般面試的時(shí)候會(huì)這樣問(wèn)

請(qǐng)寫一個(gè)單例延遲加載的例子,這個(gè)就需要用到懶漢式。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    激情视频在线视频在线视频 | 日韩免费国产91在线| 国产精品一区二区视频| 日韩高清一区二区三区四区| 欧美大粗爽一区二区三区| 欧美91精品国产自产| 在线懂色一区二区三区精品| 国产精品白丝一区二区| 黄色片国产一区二区三区| 日韩一区二区三区有码| 超碰在线播放国产精品| 在线视频免费看你懂的| 日韩在线欧美一区二区| 一二区中文字幕在线观看| 国产精品99一区二区三区| 噜噜中文字幕一区二区| 亚洲中文在线中文字幕91| 日韩欧美一区二区不卡视频| 99日韩在线视频精品免费| 国产欧美一区二区久久| 99热九九热这里只有精品| 在线懂色一区二区三区精品| 国产免费一区二区不卡| 欧美午夜一级艳片免费看| 日本午夜免费福利视频 | 国产免费人成视频尤物| 欧美色婷婷综合狠狠爱| 日本中文在线不卡视频| 亚洲欧洲在线一区二区三区| 欧洲精品一区二区三区四区| 五月综合激情婷婷丁香| 国产精品内射婷婷一级二级| 污污黄黄的成年亚洲毛片| 美国黑人一级黄色大片| 欧美日韩校园春色激情偷拍| 亚洲欧洲一区二区综合精品| 少妇福利视频一区二区| 亚洲国产欧美久久精品| 国产午夜在线精品视频| 黄色片一区二区在线观看| 亚洲专区一区中文字幕|