- 面向?qū)ο蟮奶卣髦环庋b
- 面向?qū)ο蟮奶卣髦^承
- 方法重寫(override/overWrite)
- 方法的重載(overload)和重寫(override)的區(qū)別:
- 面向?qū)ο筇卣髦憾鄳B(tài)
- Instanceof關(guān)鍵字的使用
- JAVA中的JUnit單元測(cè)試
- 包裝類(WrApper)的使用
- 類的成員之四:代碼塊(初始化塊)
- 模板方法設(shè)計(jì)模式(TemplateMethod)
- Java8中關(guān)于接口的改進(jìn)
- 類的內(nèi)部成員之五:內(nèi)部類
- 3. 抽象類和接口有哪些共同點(diǎn)和區(qū)別?
Java的面向?qū)ο?/h1>
1.java類及類的成員:屬性,方法,構(gòu)造器; 代碼塊,內(nèi)部類
2.面向?qū)ο蟮娜筇卣鳎悍庋b性,繼承性,多態(tài)性
3.其他關(guān)鍵字:this,super,static,final,abstract,interface,package,import等
類 = 屬性 + 方法
1.屬性 = 成員變量 = field = 域,字段
2.行為 = 方法 = 成員方法 = 函數(shù) = method
3.創(chuàng)建類的對(duì)象 = 類的實(shí)例化 = 實(shí)例化對(duì)象
類和對(duì)象的使用(面向?qū)ο笏枷氲穆涞貙?shí)現(xiàn))
1.創(chuàng)建類,設(shè)計(jì)類的成員
2.創(chuàng)建類的對(duì)象
3.通過(guò)“對(duì)象.屬性”或“對(duì)象.方法”調(diào)用對(duì)象的結(jié)構(gòu)
對(duì)象的內(nèi)存分析
類的成員之一屬性
類中屬性的使用
屬性(成員變量) vs 局部變量
1.相同點(diǎn):
1.1 定義變量的格式:數(shù)據(jù)類型 變量名 = 變量值
1.2 先聲明,后使用
1.3 變量都有其對(duì)應(yīng)的作用域
2.不同點(diǎn):
2.1 在類中聲明的位置的不同
屬性:直接定義在類的一對(duì){}內(nèi)
局部變量:聲明在方法內(nèi)、方法形參、代碼塊內(nèi)、構(gòu)造器形參、構(gòu)造器內(nèi)部的變量
2.2 關(guān)于 權(quán)限修飾符 的不同
屬性:可以在聲明屬性時(shí),指明其權(quán)限,使用權(quán)限修飾符。
常用的權(quán)限修飾符:private、public、缺省、protected —>封裝性
目前,大家聲明屬性時(shí),都使用缺省就可以了。
局部變量:不可以使用權(quán)限修飾符。
2.3 默認(rèn)初始化值的情況:
屬性:類的屬性,根據(jù)其類型,都有默認(rèn)初始化值。
整型(byte、short、int、long):0
浮點(diǎn)型(float、double):0.0
字符型(char):0 (或’u0000’)
布爾型(boolean):false
引用數(shù)據(jù)類型(類、數(shù)組、接口):null
局部變量: 沒(méi)有默認(rèn)初始化值。
意味著,我們?cè)谡{(diào)用局部變量之前,一定要顯式賦值。
特別地:形參在調(diào)用時(shí),我們賦值即可。
2.4 在內(nèi)存中加載的位置:
屬性:加載到堆空間中 (非static)
局部變量:加載到棧空間
return關(guān)鍵字的作用
1.結(jié)束方法
2.(返回?cái)?shù)據(jù))針對(duì)返回值類型的方法,使用“return 數(shù)據(jù)”方法返回?cái)?shù)據(jù)
一,談?wù)勀銓?duì)面向?qū)ο笾蓄惡蛯?duì)象的理解,并指出二者的關(guān)系?
類:對(duì)一類事務(wù)的描述,是抽象的,概念上的定義
對(duì)象:是實(shí)際存在的,該類事物的每個(gè)個(gè)體,因而稱為實(shí)例(instance)
面向?qū)ο蟪绦蛟O(shè)計(jì)的重點(diǎn)是類的設(shè)計(jì),,設(shè)計(jì)類,就是設(shè)計(jì)類的成員
二者的關(guān)系:對(duì)象是類派生(new)出來(lái)的
在開(kāi)發(fā)中,我們跟客戶查詢進(jìn)行交互,需要提供一個(gè)類,這個(gè)API給我們提供好了叫Scanner類,這就是類的概念
我們真正執(zhí)行的時(shí)候,我需要?jiǎng)?chuàng)建Scanner的對(duì)象,通過(guò)這個(gè)對(duì)象來(lái)操作它的功能方法,去完成我們和客戶的交互。
二,面向?qū)ο笏枷氲捏w現(xiàn)一:類和對(duì)象的創(chuàng)建和執(zhí)行操作有哪三步?
①創(chuàng)建類
②類的實(shí)例化
③調(diào)用對(duì)象的結(jié)構(gòu):“對(duì)象.屬性”,“對(duì)象.方法”
三,面向?qū)ο笈c面向過(guò)程(理解)
1.面向過(guò)程:強(qiáng)調(diào)的是功能行為,以函數(shù)為最小單位,考慮 怎么做
2.面向?qū)ο螅簭?qiáng)調(diào)具備了功能的對(duì)象,以類/對(duì)象為最小單位,考慮 誰(shuí)來(lái)做
四,萬(wàn)事萬(wàn)物皆對(duì)象
1.在java語(yǔ)言范疇中,我們都將功能,結(jié)構(gòu)等封裝到類中,通過(guò)類的實(shí)例化,來(lái)調(diào)用具體的功能結(jié)構(gòu)
2.涉及到j(luò)ava語(yǔ)言與前端html,后端數(shù)據(jù)庫(kù)交互時(shí),前后端的結(jié)構(gòu)在java層面交互時(shí),都體現(xiàn)為類,對(duì)象
五,方法 重載 (Overload)
判斷條件:同類同方法名參數(shù)列表不同
參數(shù)列表值得是(參數(shù)的個(gè)數(shù)/種類 參數(shù)的順序)
六,方法的形參的傳遞機(jī)制
形參:方法定義時(shí),聲明的小括號(hào)內(nèi)的參數(shù)
實(shí)參:方法調(diào)用時(shí),實(shí)際傳遞給形參的數(shù)據(jù)
值傳遞機(jī)制:
如果參數(shù)是 基本數(shù)據(jù)類型 ,此時(shí)實(shí)參賦給形參的是實(shí)參真是存儲(chǔ)的 數(shù)據(jù)值
如果參數(shù)是 引用數(shù)據(jù)類型 ,此時(shí)實(shí)參給形參的是實(shí)參存儲(chǔ)數(shù)據(jù)的 地址值
面向?qū)ο蟮奶卣髦环庋b
封裝:
程序設(shè)計(jì)追求“高內(nèi)聚,低耦合”
高內(nèi)聚:類的內(nèi)部數(shù)據(jù)操作細(xì)節(jié)自己完成,不允許外部干涉
低耦合:僅對(duì)外暴露少量的方法用于使用
把該隱藏的隱藏起來(lái),該暴露的暴露出來(lái)。這就是封裝性的設(shè)計(jì)思想
封裝性
1.私有的 屬性 ,提供公共的(public)方法來(lái)獲取get和設(shè)置set
2.不對(duì)外暴露的私有 方法
3.單例模式。。。(構(gòu)造器私有化)
4.如果不希望 類 在包外被調(diào)用,可以將類設(shè)置為缺省的
封裝性的體現(xiàn),需要權(quán)限修飾符來(lái)配合
1.Java規(guī)定的4中權(quán)限(從小到大排序):private,缺省(default),protected,public
2.4種權(quán)限可以用來(lái)修飾類及類的內(nèi)部結(jié)構(gòu):屬性,方法,構(gòu)造器,內(nèi)部類
修飾類的話,只能使用缺省,public
總結(jié):Java提供了4種權(quán)限修飾符來(lái)修飾類及類的內(nèi)部結(jié)構(gòu),體現(xiàn)類及類的內(nèi)部結(jié)構(gòu)在被調(diào)用時(shí)的可見(jiàn)性的大小
類的成員之三 構(gòu)造器
一,構(gòu)造器(構(gòu)造方法constructor)的使用: 創(chuàng)建對(duì)象,給對(duì)象進(jìn)行初始化
構(gòu)造器不是方法,它就是創(chuàng)建對(duì)象的,獨(dú)立的
constructor:建造。construction:CCB constructor:建設(shè)者
//創(chuàng)建類的對(duì)象: new+構(gòu)造器
Person p = new Person();
二,說(shuō)明:
1.如果沒(méi)有顯式的定義類的改造器的話,則系統(tǒng)默認(rèn)提供一個(gè)空參的構(gòu)造器
2.定義構(gòu)造器的格式:權(quán)限修飾符 類型(【參數(shù)列表】){}
public Person(){
}
public Person(String name){
}
3一個(gè)類中可以有多個(gè)構(gòu)造器,一個(gè)類中定義多個(gè)構(gòu)造器,彼此構(gòu)成重載
4.我們顯式的定義了類的構(gòu)造器之后,系統(tǒng)就不再提供默認(rèn)的空構(gòu)造器
5.一個(gè)類中,至少會(huì)有一個(gè)構(gòu)造器(擁有創(chuàng)建對(duì)象的能力)
總結(jié):屬性賦值的先后順序
- 默認(rèn)初始化
- 顯式初始化(在屬性的類中)
- 構(gòu)造器中賦值(有參構(gòu)造器)
- 通過(guò)“對(duì)象.方法”或“對(duì)象.屬性”的方式,賦值(set方法。。。。)
JavaBean
JavaBean是一種Java語(yǔ)言寫成的可重用的組件
所謂的JavaBean,是指符合以下標(biāo)準(zhǔn)的Java類:
- 類是公共的
- 有一個(gè)無(wú)慘的公共的構(gòu)造器
- 有屬性,且有對(duì)應(yīng)的get,set方法
用戶可以使用JavaBean將功能、處理、值、數(shù)據(jù)庫(kù)訪問(wèn)和其他任何可以用Java代碼創(chuàng)造的對(duì)象進(jìn)行打包,并且其他的開(kāi)發(fā)者可以通過(guò)內(nèi)部的JSP頁(yè)面、Servlet、其他JavaBean、applet程序或者應(yīng)用來(lái)使用這些對(duì)象。用戶可以認(rèn)為JavaBean提供了一種隨時(shí)隨地的復(fù)制和粘貼的功能,而不用關(guān)心任何改變。
關(guān)鍵字this
1.this可以用來(lái)修飾、調(diào)用: 屬性、方法、構(gòu)造器
2.this修飾屬性和方法:
this理解為: 當(dāng)前對(duì)象或當(dāng)前正在創(chuàng)建的對(duì)象
3.this調(diào)用構(gòu)造器
- 我們?cè)陬惖臉?gòu)造器中,可以顯式的使用"this(形參列表)"方式,調(diào)用本類中指定的其他構(gòu)造器
- 構(gòu)造器中不能通過(guò)"this(形參列表)"方式調(diào)用自己
public Person(int age){ this(); //必須放在當(dāng)前構(gòu)造器的首行 this.age = age; }
package關(guān)鍵字的使用
1.為了更好的實(shí)現(xiàn)項(xiàng)目中類的管理,提供包的概念
2.使用package聲明類或接口所屬的包,聲明在原文件的首行
3.包,屬于標(biāo)識(shí)符,遵循標(biāo)識(shí)符的命名規(guī)范
注意:同一個(gè)包下,不能命名同名的接口,類。
import關(guān)鍵字的使用
import:導(dǎo)入
1.在源文件中顯示的使用import結(jié)構(gòu)導(dǎo)入指定包下的類,接口
2.聲明在包的聲明和類的聲明之間
3.同一個(gè)包下的類或接口不用import
4.import static :導(dǎo)入指定類或接口中的靜態(tài)結(jié)構(gòu):屬性或方法
MVC設(shè)計(jì)模式
面向?qū)ο蟮奶卣髦^承
一,繼承性的好處
- 減少了代碼的冗余,提高了代碼的復(fù)用性
- 便于功能的擴(kuò)展
- 為之后多態(tài)性的使用,提供了前提
二,繼承的格式:class A extends B{}
- A:子類,派生類,subclass
- B:父類,超類,基類,subperclass
體現(xiàn):子類A繼承父類B,子類A中就獲取了父類B中聲明所有的屬性和方法
私有也會(huì)被子類繼承,只是因?yàn)闄?quán)限,子類無(wú)法直接訪問(wèn)。
(兒子繼承了父親的銀行卡,銀行卡是私有屬性,兒子不知道密碼,需要通過(guò)父類中的public get()方法獲取,,獲取了父類的所有屬性(包括私有屬性),只是不能直接調(diào)用)
一個(gè)子類只能有一個(gè)父類(java中類的單繼承性),一個(gè)父類可以有多個(gè)子類
所有的java類(除java.lang.Object類之外)都直接或間接繼承于java.lang.Object類
方法重寫(override/overWrite)
1.重寫:子類繼承父類以后,可以對(duì)父類中同名同參數(shù)的方法,進(jìn)行覆蓋操作
2.應(yīng)用:重寫以后,當(dāng)創(chuàng)建子類對(duì)象以后,通過(guò)子類對(duì)象調(diào)用父類的同名同參的方法時(shí),實(shí)際上執(zhí)行的是子類重寫父類的方法
3.重寫的規(guī)定:
- 子類重寫的方法的方法名和形參列表與父類的被重寫的方法名和參數(shù)列表相同
- 子類重寫的方法的權(quán)限修飾符不小于父類的被重寫的方法的權(quán)限修飾符特殊情況:子類不能重寫父類中聲明為private權(quán)限的方法(私有方法不能被重寫)
- 返回值類型如果父類是void則子類也要是void;父類是A類型,則子類返回值類型可以是A類型或A的子類
- 子類重寫的方法拋出的異常類型不大于父類被重寫的方法拋出的異常類型
子類和父類的同名同參的方法要么都聲明為非static的(考慮重寫),要么都聲明為static的(不重寫)
方法的重載(overload)和重寫(override)的區(qū)別:
在開(kāi)發(fā)中只需要注意:
重載:同一類中同名不同參
重寫:父子類中同名同參
重載參數(shù)列表必須不同,重寫參數(shù)列表必須相同
關(guān)鍵字:super
- super理解為:父類的
- super可以用來(lái)調(diào)用:屬性,方法,構(gòu)造器
- super的使用:
3.1 我們可以在子類的方法或構(gòu)造器中。通過(guò)使用"super.屬性或"super.方法"的方式,顯式的調(diào)用父類中聲明的屬性或方法。但是,通常情況下,我們習(xí)慣省略"super." 3.2特殊情況:當(dāng)子類和父類中定義了同名的屬性時(shí),我們要想在子類中調(diào)用父類中聲明的屬性,則必須顯式的使用"super.屬性"的方式,表明調(diào)用的是父類中聲明的屬性。 3.3特殊情況:當(dāng)子類重寫了父類中的方法以后,我們想在子類的方法中調(diào)用父類中被重寫的方法時(shí),則必須顯式的使用"super.方法"的方式,表明調(diào)用的是父類中被重寫的方法。 - super調(diào)用構(gòu)造器
4.1我們可以在子類的構(gòu)造器中顯式的使用"super(形參列表)"的方式,調(diào)用父類中聲明的指定的構(gòu)造器 4.2 "super(形參列表)“的使用,必須聲明在子類構(gòu)造器的首行! 4.3我們?cè)陬惖臉?gòu)造器中,針對(duì)于”“this(形參列表)“或"super(形參列表)“只能二選一,不能同時(shí)出現(xiàn) 4.4在構(gòu)造器的首行,沒(méi)有顯式的聲明"this(形參列表)“或"super(形參列表)””,則默認(rèn)調(diào)用的是父類中空參的構(gòu)造器:super() 4.5 在類的多個(gè)構(gòu)造器中,至少有一個(gè)類的構(gòu)造器中使用了"super(形參列表)”,調(diào)用父類中的構(gòu)造器
this(形參列表):本類重載的其它的構(gòu)造器(首行)
super(形參列表):調(diào)用父類中指定的構(gòu)造器(首行 ,默認(rèn)是super)
子類對(duì)象的實(shí)例化過(guò)程
1.從結(jié)果上看:(繼承性)
子類繼承父類后,就獲取了父類中聲明的屬性或方法
創(chuàng)建子類的對(duì)象,在堆空間中,就會(huì)加載所有父類中聲明的屬性
2.從過(guò)程上來(lái)看
當(dāng)我們通過(guò)子類的構(gòu)造器創(chuàng)建子類對(duì)象時(shí),我們一定會(huì)直接或間接的調(diào)用其父類的構(gòu)造器,進(jìn)而調(diào)用父類的構(gòu)造器,直到調(diào)用了java.lang.Object類中空參的構(gòu)造器為止,正因?yàn)榧虞d過(guò)所有的父類的結(jié)構(gòu),所以才可以看到內(nèi)存中有父類中的結(jié)構(gòu),子類對(duì)象才可以考慮進(jìn)行調(diào)用。
明確,雖然創(chuàng)建子類對(duì)象時(shí),調(diào)用了父類的構(gòu)造器,但是自始至終就創(chuàng)建了一個(gè)對(duì)象,即為new的子類對(duì)象
面向?qū)ο筇卣髦憾鄳B(tài)
理解多態(tài)性:可以理解為一個(gè)事物的多種形態(tài)
父類的引用指向子類的對(duì)象
多態(tài)的使用:當(dāng)調(diào)用子父類同名同參數(shù)的方法時(shí),實(shí)際執(zhí)行的是子類重寫父類的方法————虛擬方法調(diào)用
虛擬方法調(diào)用(多態(tài)情況下)
子類中定義了與父類同名同參數(shù)的方法,在多態(tài)情況下,將此時(shí) 父類的方法 稱為 虛擬方法 ,父類根據(jù)賦給它的不同子類對(duì)象,動(dòng)態(tài)調(diào)用屬于子類的該方法。這樣的方法調(diào)用在編譯期是無(wú)法確定的。(編譯看左,運(yùn)行看右)
多態(tài)是編譯時(shí)行為還是運(yùn)行時(shí)行為?
運(yùn)行時(shí)行為
- 有了對(duì)象的多態(tài)性以后,我們?cè)诰幾g期,只能調(diào)用父類中聲明的方法,但在運(yùn)行期,我們實(shí)際執(zhí)行的是子類重寫父類的方法
- 總結(jié):編譯看左,運(yùn)行看右,new誰(shuí)執(zhí)行誰(shuí)
- 多態(tài)性使用前提:類的繼承關(guān)系,方法的重寫
- 為什么要有多態(tài)性?:
- 對(duì)象的多態(tài)性,只適用于方法,不適用于屬性屬性的值(編譯和運(yùn)行都看左邊)
談?wù)勀銓?duì)多態(tài)性的理解:
1.實(shí)現(xiàn)代碼的通用性
2.Object類中定義的public boolean equals(object obj){ }
JDBC:使用java程序操作(獲取數(shù)據(jù)庫(kù)連接、CRUD)數(shù)據(jù)庫(kù)(MySQL、oracle、DB2、sQL Server)
3.抽象類、接口的使用肯定體現(xiàn)了多態(tài)性。(抽象類、接口不能實(shí)例化)
向上轉(zhuǎn)型:(引用是父類,對(duì)象是子類)-- 多態(tài);
向下轉(zhuǎn)型:(引用 子類,對(duì)象 子類) – 本態(tài),
多態(tài)性只針對(duì)虛擬方法調(diào)用(普通方法)
為什么使用向下轉(zhuǎn)型:
- 有了對(duì)象的多態(tài)性以后,內(nèi)存中實(shí)際上是加載了子類特有的屬性和方法,但是由于變量聲明為父類類型,導(dǎo)致編譯時(shí),只能調(diào)用父類中聲明的屬性和方法。子類特有的屬性和方法不能調(diào)用
- 如何才能調(diào)用子類特有的屬性和方法?
- 向下轉(zhuǎn)型:使用強(qiáng)制類型轉(zhuǎn)換符
Person p2 = new Man(); //使用強(qiáng)轉(zhuǎn)時(shí),有可能出現(xiàn)類型轉(zhuǎn)換異常 Man m1 = (Man)p2;
使用時(shí)的注意點(diǎn):
使用強(qiáng)轉(zhuǎn)時(shí),可能出現(xiàn)classCastException的異常。
為了避免在向下轉(zhuǎn)型時(shí)出現(xiàn)ClassCastException的異常,我們?cè)谙蛳罗D(zhuǎn)型之前,先進(jìn)行instanceof的判斷,一旦返回true,就進(jìn)行向下轉(zhuǎn)型。如果返回false,不進(jìn)行向下轉(zhuǎn)型。
Instanceof關(guān)鍵字的使用
a instanceof A:判斷 對(duì)象a 是否是 類A 的實(shí)例。如果是,返回true;如果不是,返回false。
使用情景:為了避免在向下轉(zhuǎn)型時(shí)出現(xiàn)類型轉(zhuǎn)換異常,我們?cè)谙蛳罗D(zhuǎn)型之前,先進(jìn)行instanceof的判斷,一旦返回true,就進(jìn)行向下轉(zhuǎn)型。如果返回false,不進(jìn)行向下轉(zhuǎn)型。
如果a instanceof A 返回true, 則a instanceof B 也返回true。其只,類B是類A的父類
要求a所屬的類與類A必須是子類和父類的關(guān)系,否則編譯錯(cuò)誤。
1.多態(tài)練習(xí)——重寫方法
java.lang.object類
1.object類是所有Java類的根父類
2.如果在類的聲明中未使用extends關(guān)鍵字指明其父類,則默認(rèn)父類為java.lang.object類
3.object類中的功能(屬性、方法)就具有通用性。
屬性:無(wú)
方法: equals() / tostring() / getclass() /hashcode() / clone() / finalize()
wait() 、 notify( )、notifyAll()
- Object類只聲明了一個(gè)空參的構(gòu)造器
JDK API 1.6
垃圾回收
- 垃圾回收機(jī)制只回收VM堆內(nèi)存里的對(duì)象空間。
- 對(duì)其他物理連接,比如數(shù)據(jù)庫(kù)連接、輸入流輸出流、Socket連接無(wú)能為力
- 現(xiàn)在的JVM有多種垃圾回收實(shí)現(xiàn)算法,表現(xiàn)各異。
- 垃圾回收發(fā)生具有不可預(yù)知性,程序無(wú)法精確控制垃圾回收機(jī)制執(zhí)行。
- 可以將對(duì)象的引用變量設(shè)置為null,暗示垃圾回收機(jī)制可以回收該對(duì)象。
- 程序員可以通過(guò)System.gc()或者Runtime.getRuntime().gc()來(lái)通知系統(tǒng)進(jìn)行垃圾回收,會(huì)有一些效果,但是系統(tǒng)是否進(jìn)行垃圾回收依然不確定。
- 垃圾回收機(jī)制回收任何對(duì)象 之前 ,總會(huì)先調(diào)用它的finalize方法(如果覆蓋該方法,讓一個(gè)新的引用變量重新引用該對(duì)象,則會(huì)重新激活對(duì)象)。|
- 永遠(yuǎn)不要主動(dòng)調(diào)用某個(gè)對(duì)象的finalize方法,應(yīng)該交給垃圾回收機(jī)制調(diào)用。
equals()方法
==與equals()區(qū)別?
==運(yùn)算符
- 可以使用在 基本數(shù)據(jù)類型 變量和 引用數(shù)據(jù)類型 變量中
- 如果比較的是基本數(shù)據(jù)類型變量:比較兩個(gè)變量保存的數(shù)據(jù)是否相等(不一定類型相同)
如果比較的是引用數(shù)據(jù)類型變量:比較兩個(gè)對(duì)象的地址值是否相同,即兩個(gè)引用是否指向同一個(gè)對(duì)象實(shí)體
equals()方法
- 是一個(gè)方法,而非運(yùn)算符
- 只使用于引用數(shù)據(jù)類型
- object類中equals()的定義
public boolean equals (Object obi){
return (this == obj);
}
說(shuō)明: Object類中定義的equals()和==的作用是相同的:比較兩個(gè)對(duì)象的地址值是否相同.即兩個(gè)引用是否指向同一個(gè)對(duì)象實(shí)體
- 像String,Data,F(xiàn)ile,包裝類等都重寫了Object類中的equals()方法。重寫后,比較的不是兩個(gè)引用的地址是否相同,而是比較兩個(gè)對(duì)象的“實(shí)體內(nèi)容”是否相同
public static void main(String[] args) {
Date data1 = new Date(32432525324L);
Date data2 = new Date(32432525324L);
System.out.println(data1.equals(data2));//true
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2));//true
System.out.println(str1 == str2); //false
}
- 通常情況下,我們自定義的類如果使用equals()的話,也通常是比較兩個(gè)對(duì)象的“實(shí)體內(nèi)容”是否相同。那么我們就需要對(duì)Object類中的equals()方法重寫.重寫的原則:比較兩個(gè)對(duì)象的實(shí)體內(nèi)容是否相同
toString()
- 當(dāng)我們輸出一個(gè)對(duì)象的應(yīng)用時(shí),實(shí)際上就是調(diào)用當(dāng)前對(duì)象的toString()方法
- 像String,Date,File,包裝類等都重寫了Object類中的toString()方法使得在調(diào)用對(duì)象的toString()時(shí),返回“實(shí)體內(nèi)容”信息
- 自定義類也可以重寫toString()方法,當(dāng)調(diào)用此方法時(shí),返回對(duì)象的“實(shí)體內(nèi)容”
Java中的JUnit單元測(cè)試
步驟;
1.創(chuàng)建Java類,進(jìn)行單元測(cè)試。
此時(shí)的Java類要求:
①此類是public的 ②此類提供公共的無(wú)參的構(gòu)造器
2.此類中聲明單元測(cè)試方法。
此時(shí)的單元測(cè)試方法: 方法的權(quán)限是public,沒(méi)有返回值,沒(méi)有形參
3.此單元測(cè)試方法上需要聲明注解:@Test,并在單元測(cè)試類中導(dǎo)入:import org.junit.Test;
4.聲明好單元測(cè)試方法以后,就可以在方法體內(nèi)測(cè)試相關(guān)的代碼。
包裝類(Wrapper)的使用
1.java提供了8種基本數(shù)據(jù)類型對(duì)應(yīng)的包裝類,使得基本數(shù)據(jù)類型的變量具有類的特征
2.掌握的:基本數(shù)據(jù)類型、包裝類、String三者之間的相互轉(zhuǎn)換
基本數(shù)據(jù)類型—>包裝類:調(diào)用包裝類的構(gòu)造器 (對(duì)象參數(shù))
包裝類—>基本數(shù)據(jù)類型:調(diào)用包裝類x×x的x×xValue() (方便做±*/運(yùn)算)
JDK 5.0新特性:自動(dòng)裝箱與自動(dòng)拆箱
基本數(shù)據(jù)類型、包裝類—>String類型調(diào)用String重載的valueOf(Xxx Xxx)
String類型—>基本數(shù)據(jù)類型、包裝類:調(diào)用包裝類的parseXxx(String s)
測(cè)試:
三元式中 表達(dá)式1和表達(dá)式2類型不同時(shí)
1.一種類型為char,short,byte,另一種為int常量,而且該常量能被前三種類型表示,則返回的是前三種的類型;
2.若int類型是變量,則會(huì)將操作數(shù)類型提升,返回類型為類型提升后的類型。
System.out.println(true ? 97 : 'a'); //a
System.out.println(true ? 1 : 2.0); //1.0
System.out.println(true ? 2.0 : 1); //2.0
- Integer內(nèi)部定義了IntegerCache結(jié)構(gòu),IntegerCache中定義了Integer[],保存了從-128 ~127 范圍的整數(shù)。
- 如果我們使用自動(dòng)裝箱的方式,給Integer賦值的范圍在 -128~127范圍內(nèi)時(shí),可以直接使用數(shù)組中的元素,不用再去new了。目的:提高效率
1.為什么要有包裝類(封裝類)
為了使基本數(shù)據(jù)類型的變量具有類的特征,引入包裝類。
static關(guān)鍵字的使用
1.static:靜態(tài)的
2.static可以來(lái)修飾:屬性,方法,代碼塊,內(nèi)部類
3.使用static修飾屬性:靜態(tài)變量
3.1屬性,按是否使用static修飾,又分為:靜態(tài)屬性vs非靜態(tài)屬性(實(shí)例變量)
- 實(shí)例變量:我們創(chuàng)建了類的多個(gè)對(duì)象,每個(gè)對(duì)象都獨(dú)立的擁有一套類中的非靜態(tài)屬性。當(dāng)修改其中一個(gè)對(duì)象中的非靜態(tài)屬性時(shí),不會(huì)導(dǎo)致其他對(duì)象中同樣的屬性值的修改。
- 靜態(tài)變量:我們創(chuàng)建了類的多個(gè)對(duì)象,多個(gè)對(duì)象共享同一個(gè)靜態(tài)變量。當(dāng)通過(guò)某一個(gè)對(duì)象修改靜態(tài)變量時(shí),會(huì)導(dǎo)致其他對(duì)象調(diào)用此靜態(tài)變量時(shí),是修改過(guò)了的。3.2 static修飾屬性的其他說(shuō)明:
- 靜態(tài)變量隨著類的加載而加載。可以通過(guò)"類.靜態(tài)變量"的方式進(jìn)行調(diào)用
- 靜態(tài)變量的加載要早于對(duì)象的創(chuàng)建。
- 由于類只會(huì)加載一次,則靜態(tài)變量在內(nèi)存中也只會(huì)存在一份: 存在方法區(qū)的靜態(tài)域中
3.3 靜態(tài)屬性舉例:System.out; Math.PI;
4.使用static修飾方法:靜態(tài)方法
① 隨著類的加載而加載,可以通過(guò)"類.靜態(tài)方法"的方式進(jìn)行調(diào)用
②
調(diào)用 方法 |
靜態(tài)方法 |
非靜態(tài)方法 |
類 |
yes |
no |
對(duì)象 |
yes |
yes |
③ 靜態(tài)方法中,只能調(diào)用靜態(tài)的方法或?qū)傩?/p>
非靜態(tài)方法中,既可以調(diào)用非靜態(tài)的方法或?qū)傩裕部梢哉{(diào)用靜態(tài)的方法或?qū)傩?/p>
- static注意點(diǎn):5.1 在靜態(tài)的方法內(nèi),不能使用this關(guān)鍵字、super關(guān)鍵字5.2 關(guān)于靜態(tài)屬性和靜態(tài)方法的使用,大家都從生命周期的角度去理解。
- 開(kāi)發(fā)中,如何確定一個(gè) 屬性 是否要聲明為static的?屬性是可以被多個(gè)對(duì)象所共享的,不會(huì)隨著對(duì)象的不同而不同的。類中的常量也常常聲明為static開(kāi)發(fā)中,如何確定一個(gè) 方法 是否要聲明為static的?操作靜態(tài)屬性的方法,通常設(shè)置為static的工具類中的方法,習(xí)慣上聲明為static的。 比如:Math、Arrays、Collections
靜態(tài)的方法屬性在類加載的時(shí)候被創(chuàng)建,靜態(tài)的方法可以調(diào)用靜態(tài)的屬性,
非靜態(tài)的方法屬性在對(duì)象實(shí)例化的時(shí)候被創(chuàng)建,可以調(diào)用靜態(tài)的方法和屬性
設(shè)計(jì)模式
設(shè)計(jì)模式是在大量的實(shí)踐中總結(jié)和理論化之后優(yōu)選的代碼結(jié)構(gòu),編碼風(fēng)格,以及解決問(wèn)題的思考方式(套路)
單例(Singleton)設(shè)計(jì)模式
所謂類的單例設(shè)計(jì)模式,就是采取一定的方法保證在整個(gè)的軟件系統(tǒng)中,對(duì) 某個(gè)類只能存在一個(gè)對(duì)象實(shí)例 。
單例模式的優(yōu)點(diǎn):由于單例模式只生成一個(gè)實(shí)例, 減少了系統(tǒng)性能開(kāi)銷 。
實(shí)現(xiàn)步驟:
1.私有化類的構(gòu)造器
2.內(nèi)部創(chuàng)建類的對(duì)象,要求此對(duì)象也必須聲明為靜態(tài)的
3.提供公共的靜態(tài)的方法,返回類的對(duì)象
根據(jù)實(shí)例化對(duì)象的時(shí)刻不同分為:餓漢式和懶漢式
餓漢式:初始化的時(shí)候?qū)嵗瘜?duì)象
懶漢式:第一次調(diào)用的時(shí)候創(chuàng)建,((每次被調(diào)用先判斷是否nul,如果對(duì)象已經(jīng)被實(shí)例化,直接用l))
餓漢式:
好處:線程安全的
壞處:對(duì)象加載時(shí)間長(zhǎng)
懶漢式:
好處:延遲對(duì)象的創(chuàng)建
壞處:目前是線程不安全的 ------>到多線程內(nèi)容,
懶漢式相對(duì)好一點(diǎn),用的時(shí)候才被創(chuàng)建,餓漢式不管用不用都在類加載時(shí)候創(chuàng)建對(duì)象
單例模式設(shè)計(jì)模式----應(yīng)用場(chǎng)景
類的成員之四:代碼塊(初始化塊)
- 代碼塊的作用:用來(lái)初始化類、對(duì)象
- 代碼塊如果有修飾的話,只能使用static.
- 分類:靜態(tài)代碼塊 vs 非靜態(tài)代碼塊
- 靜態(tài)代碼塊內(nèi)部可以有輸出語(yǔ)句隨著類的加載而 執(zhí)行 ,而且只執(zhí)行一次作用:初始化類的信息如果一個(gè)類中定義了多個(gè)靜態(tài)代碼塊,則按照聲明的先后順序執(zhí)行靜態(tài)代碼塊的執(zhí)行要優(yōu)先于非靜態(tài)代碼塊的執(zhí)行靜態(tài)代碼塊內(nèi)只能調(diào)用靜態(tài)的屬性、靜態(tài)的方法,不能調(diào)用非靜態(tài)的結(jié)構(gòu)
- 非靜態(tài)代碼塊內(nèi)部可以有輸出語(yǔ)句隨著對(duì)象的創(chuàng)建而 執(zhí)行
每創(chuàng)建一個(gè)對(duì)象,就執(zhí)行一次非靜態(tài)代碼塊作用:可以在創(chuàng)建對(duì)象時(shí),對(duì)對(duì)象的屬性等進(jìn)行初始化如果一個(gè)類中定義了多個(gè)非靜態(tài)代碼塊,則按照聲明的先后順序執(zhí)行非靜態(tài)代碼塊內(nèi)可以調(diào)用靜態(tài)的屬性、靜態(tài)的方法,或非靜態(tài)的屬性,非靜態(tài)的方法
總結(jié):有父及子,靜態(tài)先行
先執(zhí)行父類的靜態(tài)代碼塊–>直接父類的靜態(tài)代碼塊—>本類的靜態(tài)代碼塊,然后父類的代碼塊–>父類的無(wú)參構(gòu)造器–>直接父類的代碼塊–>無(wú)慘構(gòu)造器—>本類的代碼塊–>無(wú)慘構(gòu)造器
對(duì)屬性可以賦值的位置:
①默認(rèn)初始化
②顯式初始化
③構(gòu)造器中初始化
④有了對(duì)象以后,可以通過(guò)"對(duì)象.屬性"或"對(duì)象.方法"的方式,進(jìn)行賦值
⑤在代碼塊中賦值
先后順序:①→②/⑤→③→④
關(guān)鍵字:final
final:最終的
- final可以用來(lái)修飾的結(jié)構(gòu):類、方法、變量(屬性,局部變量)
- final 用來(lái)修飾一個(gè)類:此類不能被其他類所繼承。比如:String類、System類、StringBuffer類(該有的功能都有了,無(wú)需擴(kuò)展功能,不用去繼承,想用就用,不用拉到)
- final 用來(lái)修飾方法:表明此方法不可以被 重寫
比如:Object類中g(shù)etClass(); - final 用來(lái)修飾變量:此時(shí)的"變量"就稱為是一個(gè)常量4.1 final修飾屬性:可以考慮賦值的位置有:顯式初始化、代碼塊中初始化、構(gòu)造器中初始化4.2 final修飾局部變量:尤其是使用final修飾形參時(shí),表明此形參是一個(gè)常量。當(dāng)我們調(diào)用此方法時(shí),給常量形參賦一個(gè)實(shí)參。一旦賦值以后,就只能在方法體內(nèi)使用此形參,但不能進(jìn)行重新賦值。
static final 用來(lái)修飾屬性:全局常量
用來(lái)修飾方法:直接通過(guò)類來(lái)調(diào)用這個(gè)方法不能被重寫
總結(jié):
1.static 修飾的屬性,相較于實(shí)例變量,有哪些特別之處(創(chuàng)建,調(diào)用,存儲(chǔ))
- 隨著類的加載而加載;早于對(duì)象的創(chuàng)建;
- 只要權(quán)限允許,可以通過(guò)”對(duì)象.static屬性”的方式進(jìn)行調(diào)用;
- 存在于方法區(qū)的靜態(tài)域
abstract關(guān)鍵字的使用
1.abstract:抽象的
2.abstract可以用來(lái)修飾的結(jié)構(gòu):類、方法
3. abstract修飾類: 抽象類
此類不能實(shí)例化
抽象類中一定有 構(gòu)造器 ,便于子類實(shí)例化時(shí)調(diào)用(涉及:子類對(duì)象實(shí)例化的全過(guò)程)
開(kāi)發(fā)中,都會(huì)提供抽象類的子類,讓子類對(duì)象實(shí)例化,完成相關(guān)的操作
- abstract修飾方法: 抽象方法
抽象方法只能有方法的聲明,沒(méi)有方法體
包含抽象方法的類,一定是一個(gè)抽象類。反之,抽象類中可以沒(méi)有抽象的方法。
若子類重寫了父類中的所有的抽象方法后,此子類方可實(shí)例化
若子類沒(méi)有重寫了父類中的所有的抽象方法后,此子類也是抽象類不能被實(shí)例化
abstract使用上的 注意點(diǎn) :
1.abstract不能用來(lái)修飾:屬性,構(gòu)造器等結(jié)構(gòu)
2.abstract不能用來(lái)修飾私有方法,靜態(tài)方法 ,final的方法,final的類
舉例:父類中有寫功能實(shí)在沒(méi)有辦法指明,子類反正又要重寫了,就給該功能抽象成抽象方法,把該類設(shè)置成抽象類
總結(jié):
抽樣類不能被實(shí)例化(只能被繼承),抽樣方法所屬的類一定是抽樣類
繼承抽樣類的子類要不把每個(gè)抽樣方法重寫,要不也是一個(gè)抽樣類
匿名子類的對(duì)象
創(chuàng)建匿名子類的匿名對(duì)象
匿名的意義就是只用一次
模板方法設(shè)計(jì)模式(TemplateMethod)
抽象類體現(xiàn)的就是一種模板模式的設(shè)計(jì),抽象類作為多個(gè)子類的通用模板,子類在抽象類的基礎(chǔ)上進(jìn)行擴(kuò)展、改造,但子類總體上會(huì)保留抽象類的行為方式。
- 解決的問(wèn)題:
當(dāng)功能內(nèi)部一部分實(shí)現(xiàn)是確定的,一部分實(shí)現(xiàn)是不確定的。這時(shí)可以
把不確定的部分暴露出去,讓子類去實(shí)現(xiàn)。
換句話說(shuō),在軟件開(kāi)發(fā)中實(shí)現(xiàn)一個(gè)算法時(shí),整體步驟很固定、通用,這些步驟已經(jīng)在父類中寫好了。但是某些部分易變,易變部分可以 抽象 出來(lái),供不同子類實(shí)現(xiàn)。這就是一種模板模式。
- 舉例:
/**
* 抽象類的應(yīng)用,模板方法的設(shè)計(jì)模式
*/
class templateTest{
public static void main(String[] args) {
SubTemplate subTemplate = new SubTemplate();
subTemplate.spendTime();
}
}
public abstract class Template {
//計(jì)算某代碼執(zhí)行所需要花費(fèi)的時(shí)間
public void spendTime(){
long start = System.currentTimeMillis();
this.code();//不確定的部分,易變得部分
long end = System.currentTimeMillis();
System.out.println();
System.out.println("程序運(yùn)行花費(fèi)的時(shí)間為:"+(end-start)+"毫秒");
}
public abstract void code();
}
class SubTemplate extends Template{
@Override
public void code() {
for (int i = 2; i < 1000; i++) {
int flag = 0;
for (int j=2;j<=Math.sqrt(i);j++){
if (i%j==0){
flag = 1;
}
}
if (flag==0){
System.out.print(i+" ");
}
}
}
}
接口interface
- 一方面,有時(shí)必須從幾個(gè)類中派生出一個(gè)子類,繼承它們所有的屬性和方法。但是,Java不支持多重繼承。有了接口,就可以得到多重繼承的效果
- 另一方面,有時(shí)必須從幾個(gè)類中抽取出一些共同的行為特征,而它們之間又沒(méi)有is-a的關(guān)系,僅僅是具有相同的行為特征而已。例如:鼠標(biāo)、鍵盤、打印機(jī)、掃描儀、攝像頭、充電器、MP3機(jī)、手機(jī)、數(shù)碼相機(jī)、移動(dòng)硬盤等都支持USB連接。
- 接口就是規(guī)范,定義的是一組規(guī)則,體現(xiàn)了現(xiàn)實(shí)世界中“如果你是/要…則必須能…”的思想。繼承是一個(gè)"是不是"的關(guān)系,而接口實(shí)現(xiàn)則是"能不能"的關(guān)系。
- 接口的本質(zhì)是契約,標(biāo)準(zhǔn),規(guī)范,就像我們的法律一樣。制定好后大家都要遵守。
接口的使用:
1.接口使用interface來(lái)定義
2.Java中,接口和類是并列的兩個(gè)結(jié)構(gòu)
3.如何定義接口:定義接口中的成員
3.1JDK7及以前:只能定義 全局常量 和 抽象方法
>全局常量:public static final的)(可以省略不寫)
>抽象方法:public abstract的
3.2JDK8:除了定義 全局常量 和 抽象方法 之外,還可以定義 靜態(tài)方法 、 默認(rèn)方法(略)
4.接口中不能定義構(gòu)造器的。意味著接口不可以實(shí)例化
5.Java開(kāi)發(fā)中,接口通過(guò)讓類去實(shí)現(xiàn)(implements)的方法來(lái)使用。
如果實(shí)現(xiàn)類覆蓋了接口中的所有抽樣方法,則此實(shí)現(xiàn)類就可以實(shí)例化
如果實(shí)現(xiàn)類沒(méi)有覆蓋接口中所有的抽象方法,則此實(shí)現(xiàn)類仍為一個(gè)抽象類
6.Java類可以實(shí)現(xiàn)多個(gè)接口---->彌補(bǔ)了Java單繼承性的局限性
格式: class AA extends BB implements CC,DD,EE{}
7.接口與接口之間可以繼承,而且可以 多繼承
8.接口的具體使用,體現(xiàn)了 多態(tài)性
9.接口,實(shí)際上就可以看做一種 規(guī)范
10.開(kāi)發(fā)中,體會(huì) 面向接口編程 !
接口定義的一種規(guī)范,面向接口編程,使得代碼更具有 通用性 或 可移植性
代理模式
代理模式是Java開(kāi)發(fā)中使用較多的一種設(shè)計(jì)模式。代理設(shè)計(jì)就是為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。
代理類和被代理類都需要實(shí)現(xiàn)這個(gè)接口,通過(guò)代理類的對(duì)象調(diào)用實(shí)現(xiàn)接口中的抽象方法時(shí),里面包含了被代理對(duì)象同名的方法的調(diào)用。
工廠模式
1.解決的問(wèn)題
實(shí)現(xiàn)了創(chuàng)建者與調(diào)用者的分離,即將創(chuàng)建對(duì)象的具體過(guò)程屏蔽隔離起來(lái),達(dá)到提高靈活性的目的。
2.具體模式
簡(jiǎn)單工廠模式。用來(lái)生產(chǎn)同一等級(jí)結(jié)構(gòu)中的任意產(chǎn)品。(對(duì)于增加新的產(chǎn)品,需要修改已有代碼)工廠方法模式:用來(lái)生產(chǎn)同一等級(jí)結(jié)構(gòu)中的固定產(chǎn)品。(支持增加任意產(chǎn)品)
抽象工廠模式。用來(lái)生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品。(對(duì)于增加新的產(chǎn)品,無(wú)能為力﹔支持增加產(chǎn)品族)
3.核心本質(zhì):
實(shí)例化對(duì)象,用工廠方法代替new操作。
將選擇實(shí)現(xiàn)類、創(chuàng)建對(duì)象統(tǒng)一管理和控制。從而將調(diào)用者跟我們的實(shí)現(xiàn)類解耦。
Java8中關(guān)于接口的改進(jìn)
Java8新特性
知識(shí)點(diǎn)1:接口中定義的靜態(tài)方法,只能通過(guò)接口來(lái)調(diào)用
知識(shí)點(diǎn)2:通過(guò)實(shí)現(xiàn)類的對(duì)象,可以調(diào)用接口中的默認(rèn)方法
如果實(shí)現(xiàn)類重寫了接口中的默認(rèn)方法,調(diào)用時(shí),任然調(diào)用的是重寫以后的方法
知識(shí)點(diǎn)3:如果子類(或?qū)崿F(xiàn)類)繼承的父類和實(shí)現(xiàn)的接口中聲明了同名同參數(shù)的方法,那么子類在沒(méi)有重寫此方法的情況下,默認(rèn)調(diào)用的是父類中的同名同參數(shù)的方法。------>類優(yōu)先原則
知識(shí)點(diǎn)4:如果實(shí)現(xiàn)類實(shí)現(xiàn)了多個(gè)接口,而這多個(gè)接口中定義了同名同參的默認(rèn)方法,那么在實(shí)現(xiàn)類沒(méi)有重寫此方法的情況下,報(bào)錯(cuò)。------>接口沖突
這就需要我們必須在實(shí)現(xiàn)類中重寫此方法
知識(shí)點(diǎn)5:如何在子類(或?qū)崿F(xiàn)類)的方法中調(diào)用父類,接口中被重寫的方法
類的內(nèi)部成員之五:內(nèi)部類
- Java中允許將一個(gè)類A聲明在另一個(gè)類B中,則類A就是內(nèi)部類,類B就是外部類
- 內(nèi)部類的分類:成員內(nèi)部類(靜態(tài),非靜態(tài)) 和局部?jī)?nèi)部類(方法內(nèi),代碼塊內(nèi),構(gòu)造器內(nèi))
- 成員內(nèi)部類:一方面,作為外部類的成員;調(diào)用外部類的結(jié)構(gòu)可以被static修飾可以被4種不同的權(quán)限修飾另一方面,作為一個(gè)類:類內(nèi)可以定義屬性、方法、構(gòu)造器等可以被final修飾,表示此類不能被繼承。言外之意,不使用final,就可以被繼承可以被abstract修飾關(guān)注如下的3個(gè)問(wèn)題4.1 如何實(shí)例化成員內(nèi)部類的對(duì)象4.2如何在成員內(nèi)部類中區(qū)分調(diào)用外部類的結(jié)構(gòu)4.3 開(kāi)發(fā)中局部?jī)?nèi)部類的使用
總結(jié)
- abstract能修飾哪些結(jié)構(gòu)? 修飾以后,有什么特點(diǎn)?,
類、方法。
類不能實(shí)例化,提供子類
抽象方法,只定義了一種功能的標(biāo)準(zhǔn)。具體的執(zhí)行,需要子類去實(shí)現(xiàn)。
- 接口是否能繼承接口?抽象類是否能實(shí)現(xiàn)(implements)接口?抽象類是否能繼承非抽象的類?,能,能,能
3. 抽象類和接口有哪些共同點(diǎn)和區(qū)別?
抽象類:類中的有的東西它都可以有,還可以有抽象方法
接口:JDK7及以前只能有:全局變量和抽樣方法 JDK8以后可以添加靜態(tài)靜態(tài)方法和默認(rèn)方法,JDK9可以定義私有方法。
相同點(diǎn):不能實(shí)例化(都可以包含抽樣方法的),都可以被繼承
不同點(diǎn):抽象類:有構(gòu)造器。接口:不能聲明構(gòu)造器
類:?jiǎn)卫^承 接口:多繼承
類與接口:多實(shí)現(xiàn)
抽象類和接口 都不能夠?qū)嵗?/strong> ,但可以定義抽象類和接口類型的 引用 。一個(gè)類如果繼承了某個(gè)抽象類或者實(shí)現(xiàn)了某個(gè)接口都需要對(duì)其中的抽象方法全部進(jìn)行實(shí)現(xiàn),否則該類仍然需要被聲明為抽象類。 接口比抽象類更加抽象 ,因?yàn)槌橄箢愔锌梢远x構(gòu)造器,可以有抽象方法和具體方法,而接口中不能定義構(gòu)造器而且其中的方法全部都是抽象方法。抽象類中的成員可以是private、默認(rèn)、protected、public的,而接口中的成員全都是public的。抽象類中可以定義成員變量,而接口中定義的成員變量實(shí)際上都是常量。有抽象方法的類必須被聲明為抽象類,而抽象類未必要有抽象方法。