1. java基礎(chǔ)概念
在 Java 這門語言體系當(dāng)中酌媒,最基礎(chǔ)的部分就是 Java SE 部分,Java 的標(biāo)準(zhǔn)版本。它包括Java最基礎(chǔ)的一些結(jié)構(gòu)秒咨,包括面向?qū)ο蟮囊恍┨匦缘鹊壤桑瑫r它也是 Java 技術(shù)基礎(chǔ)和核心。
在 Java SE 的基礎(chǔ)之上雨席,又分為了 :
Java EE(Java 的企業(yè)版)菩咨,應(yīng)用于大型企業(yè)級應(yīng)用的開發(fā)。
Java ME 主要用于嵌入式開發(fā)陡厘。
初學(xué)的時候我們都是從 Java SE 開始的抽米。
- JVM 叫 Java 虛擬機,它也是整個 Java 技術(shù)的核心雏亚。Java 語言的跨平臺就多虧了 JVM缨硝。
- JDK 叫 Java 開發(fā)工具包,沒有 JDK 就沒有辦法進(jìn)行 Java 程序的開發(fā)罢低。
- JRE 叫 Java 運行環(huán)境,如果我們需要運行一個Java程序胖笛,就得安裝 JRE网持。
Java程序基本運行原理如下圖:
2. Java 程序的構(gòu)成
一個Java程序可以認(rèn)為是一系列對象的集合,而這些對象通過調(diào)用彼此的方法來協(xié)同工作长踊。
對象(object):對象是類的一個實例功舀,有狀態(tài)和行為。例如身弊,一條狗是一個對象辟汰,它的狀態(tài)有:顏色、名字阱佛、品種帖汞;行為有:搖尾巴、叫凑术、吃等翩蘸。
類(class):類是一個模板,它描述一類對象的行為和狀態(tài)淮逊。
方法(method):方法就是行為催首,一個類可以有很多方法。邏輯運算泄鹏、數(shù)據(jù)修改以及所有動作都是在方法中完成的郎任。
實例變量:每個對象都有獨特的實例變量,對象的狀態(tài)由這些實例變量的值決定备籽。
1舶治、為什么一切都開始于一個類?
Java程序是由類組成,一個類包含方法和屬性歼疮。這是由于它的面向?qū)ο蟮奶卣鳎阂磺薪詫ο笤映椋總€對象都是一個類的實例。面向?qū)ο缶幊逃泻芏鄡?yōu)勢韩脏,比如更好的模塊化缩麸,擴展性強等
2、為什么總有一個“main”方法赡矢?
“main”方法是程序的入口杭朱,它是靜態(tài)的。 “static”是指該方法是類的一部分吹散,而不是對象的一部分弧械。
這是為什么?我們?yōu)槭裁床话岩粋€非靜態(tài)方法作為程序的入口空民? 如果方法不是靜態(tài)的刃唐,那么需要創(chuàng)建一個對象后才能使用方法。因為必須用對象去調(diào)用方法界轩。對于程序的入口画饥,這是不現(xiàn)實的。所以浊猾,程序的入口方法是靜態(tài)的抖甘。
參數(shù)“String[] args”表示一個字符串?dāng)?shù)組可以被傳入到該程序,用來初始化程序葫慎。
3. Java 關(guān)鍵字
Java 的關(guān)鍵字對 java 的編譯器有特殊的意義衔彻,他們用來表示一種數(shù)據(jù)類型,或者表示程序的結(jié)構(gòu)等偷办,關(guān)鍵字不能用作變量名艰额、方法名、類名爽篷、包名悴晰。
Java 關(guān)鍵字有如下表所列,目前共有50個Java關(guān)鍵字逐工,其中铡溪,"const"和"goto"這兩個關(guān)鍵字在Java語言中并沒有具體含義。同學(xué)們先有個印象泪喊,具體含義我們將在后續(xù)的內(nèi)容中詳細(xì)講解:
4. Java 標(biāo)識符
Java 語言中棕硫,類滑肉、變量护姆、常量灯变、方法都需要名字坦刀,我們統(tǒng)統(tǒng)稱之為 Java 標(biāo)識符.
標(biāo)識符是用來給類混坞、對象禾酱、方法、變量疫粥、接口和自定義數(shù)據(jù)類型命名的娄蔼。
關(guān)于 Java 標(biāo)識符前标,有幾點需要注意的:
1. Java 標(biāo)識符由數(shù)字,字母A-Z或者a-z和下劃線_焰望,美元符號$組成。
2. 所有的標(biāo)識符都應(yīng)該以字母A-Z或者a-z,美元符$缭付、或者下劃線_開始当犯,首位不能是數(shù)字铺峭。
3. 關(guān)鍵字不能用作標(biāo)識符。
4. 在 Java 中是區(qū)分大小寫的勤庐。
在 Java 中,還有一些約定俗成的命名規(guī)則,希望同學(xué)們在寫代碼的時候都能遵循這些規(guī)則:
1. 類和接口名。每個字的首字母大寫,含有大小寫嫂粟。例如,MyClass墨缘,HelloWorld星虹,Time 等。
2. 方法名镊讼。首字符小寫宽涌,其余的首字母大寫,含大小寫蝶棋。盡量少用下劃線卸亮。例如,myName玩裙,setTime 等兼贸。這種命名方法叫做駝峰式命名。
3. 常量名吃溅∪艿基本數(shù)據(jù)類型的常量名使用全部大寫字母,字與字之間用下劃線分隔决侈。對象常量可大小混寫螺垢。例如,SIZE_NAME赖歌。
4. 變量名甩苛。可大小寫混寫俏站,首字符小寫,字間分隔符用字的首字母大寫痊土。不用下劃線肄扎,少用美元符號。
5. 命名過程中盡量做到見名知意赁酝,方便后期查看和修改代碼犯祠,也方便其他人員的閱讀。
5. 變量
變量(variable)占據(jù)一定的內(nèi)存空間酌呆。不同類型的變量占據(jù)不同的大小衡载。Java 中的變量類型如下:
Java中主要有如下幾種類型的變量:
局部變量
類變量(靜態(tài)變量)
成員變量(非靜態(tài)變量)
變量的概念實際上來自于面向過程的編程語言。在Java中隙袁,所謂的變量實際上是基本類型 (premitive type).
6. 常量
常量代表程序運行過程中不能改變的值痰娱。我們也可以把它們理解為特殊的變量弃榨,只是它們在程序的運行過程中是不允許改變的。常量的值是不能被修改的梨睁。
常量的語法格式和變量類似鲸睛,只需要在變量的語法格式前面添加關(guān)鍵字final即可。在Java編碼規(guī)范中坡贺,要求常量名必須大寫官辈。
常量的語法格式如下:
final 數(shù)據(jù)類型 常量名稱 = 值;
final 數(shù)據(jù)類型 常量名稱1 = 值1遍坟, 常量名稱2 = 值2拳亿,……常量名稱n = 值n;
在Java語法中愿伴,常量也可以首先聲明肺魁,然后再進(jìn)行賦值,但是只能賦值一次公般,示例代碼如下:
final 用于聲明屬性(常量)万搔,方法和類,分別表示屬性一旦被分配內(nèi)存空間就必須初始化, 它的含義是“這是無法改變的”或者“終態(tài)的”官帘。
一般在 Java 里有三種注釋:
行注釋//:只注釋一行
段注釋/*...*/:注釋若干行
文檔注釋/**...*/:注釋若干行瞬雹,并寫入 javadoc文檔
7. 數(shù)據(jù)類型
- 在Java中有8種基本數(shù)據(jù)類型:
浮點型:float(4 byte), double(8 byte)
整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)
字符型: char(2 byte)
布爾型: boolean(JVM規(guī)范沒有明確規(guī)定其所占的空間大小,僅規(guī)定其只能夠取字面值"true"和"false")
對于這8種基本數(shù)據(jù)類型的變量刽虹,變量直接存儲的是“值”酗捌,因此在用關(guān)系操作符==來進(jìn)行比較時,比較的就是 “值” 本身涌哲。要注意浮點型和整型都是有符號類型的胖缤,而char是無符號類型的(char類型取值范圍為0~2^16-1).
-
非基本數(shù)據(jù)類型的變量,稱作為 引用類型的變量阀圾。String str1; str1就是引用類型的變量.
str1= new String("hello");
引用類型的變量存儲的并不是 “值”本身哪廓,也就是說并不是直接存儲的字符串"hello",而是于其指向的對象在內(nèi)存中的地址。
8. == 和 equals 的區(qū)別初烘?
==
(1) 如果作用于基本數(shù)據(jù)類型的變量涡真,則直接比較其存儲的 “值”是否相等;
int a = 2; int b = 2; a == b; // true
(2) 如果作用于引用類型的變量肾筐,則比較的是所指向的對象的地址.
String str1 = new String("hello");
String str2 = new String("hello");
str1 == str2 ; // false, str1 和str2分別指向不同的對象哆料,各自存儲的是所指向的對象在內(nèi)存中的地址,并不是“值”本身吗铐,也就是說并不是直接存儲的字符串"hello"东亦,而不同的對象在內(nèi)存中的地址不同
equals()
而想要比較對象的內(nèi)容是否相同時,Java 提供了一個特殊的方法equals()唬渗,它不適用于基本類型典阵,基本類型使用==和奋渔!=進(jìn)行比較。
(因為equals()默認(rèn)比較引用)
(1) 對于equals方法萄喳,注意:equals方法不能作用于基本數(shù)據(jù)類型的變量
(2) 如果沒有對equals方法進(jìn)行重寫卒稳,則比較的是引用類型的變量所指向的對象的地址;(那這么說他巨,這種情況下== 和 equals() 的 比較的都是引用類型的變量的值充坑,即變量所指向的對象在內(nèi)存中的地址)
(3) 諸如String、Integer染突、Double捻爷、Date等類對equals方法進(jìn)行了重寫的話,比較指向的對象所存儲的內(nèi)容是否相等份企。
Integer n1 = new Integer("hello");
Integer n2 = new Integer("hello");
n1 == n2
; //false
n1.equals(n2);
// true
9. 自動類型轉(zhuǎn)換和強制類型轉(zhuǎn)換
在Java程序中也榄,不同的數(shù)據(jù)類型有些時候需要進(jìn)行相互轉(zhuǎn)換。數(shù)據(jù)類型轉(zhuǎn)換就分為了自動類型轉(zhuǎn)換和強制類型轉(zhuǎn)換
自動類型轉(zhuǎn)換是在程序執(zhí)行過程中司志,不需要我們?nèi)ヌ厥饴暶骰蛘卟僮魈鹱希兞坑捎谛枰詣愚D(zhuǎn)換成了合適的數(shù)據(jù)類型。
自動類型轉(zhuǎn)換需要滿足下面的兩個條件:
目標(biāo)類型與原類型兼容
目標(biāo)類型的字節(jié)數(shù)大于或等于原類型字節(jié)數(shù)
基本數(shù)據(jù)類型中骂远,布爾類型boolean占有一個字節(jié)囚霸,由于其本身所代碼的特殊含義,boolean類型與其他基本類型不能進(jìn)行類型的轉(zhuǎn)換(既不能進(jìn)行自動類型的提升激才,也不能強制類型轉(zhuǎn)換)拓型, 否則,將編譯出錯瘸恼。
強調(diào):
==和!=適用于所有的基本數(shù)據(jù)類型劣挫,其他關(guān)系運算符不適用于boolean,因為boolean值只有
true
和false
东帅,比較沒有任何意義压固。==和!=也適用于所有對象,可以比較對象的引用是否相同靠闭。
引用:Java 中一切都是對象邓夕,但操作的標(biāo)識符實際是對象的一個引用。
因為兩個對象是相同的阎毅。盡管兩個對象的內(nèi)容相同,但它們的引用卻不相同点弯,==和扇调!=比較的就是對象的引用,所以結(jié)果false抢肛,再是true,如下:
練習(xí)
先想一想下面的邏輯表達(dá)是的值是 true 還是 false狼钮。然后用代碼驗證一下吧碳柱。
(5 > 2) && (4 == 5)
false || (2 < 5)
提示:C語言中,非0就是true熬芜,0就是false莲镣,然而這個規(guī)則不適用于Java,Java的int不能自動轉(zhuǎn)為boolean涎拉。參考while(true){} 而不是while(1){}瑞侮。
Java里不允許將一個數(shù)字作為布爾值使用,雖然這在C和C++是允許的鼓拧,如果要在布爾測試?yán)锸褂靡粋€非布爾值半火,需要先用一個條件表達(dá)式將其轉(zhuǎn)換成布爾值
10. 數(shù)組
先定義后使用
一維數(shù)組
也可以在數(shù)組聲明的時候初始化數(shù)組季俩,或者為它分配好空間
Java中可以將一個數(shù)組賦值給另一個數(shù)組,如:
修改a2的值酌住,a1的值也跟著變化
二維數(shù)組:
11. Java方法
我們經(jīng)常使用到System.out.println()店归,它是什么呢?
println() 是一個方法
System 是系統(tǒng)類
out 是標(biāo)準(zhǔn)輸出對象
這句語句的意思是調(diào)用系統(tǒng)類 System 中的標(biāo)準(zhǔn)輸出對象 out 中的方法 println()酪我。
在上面的語法說明中:
(1) 訪問修飾符:代表方法允許被訪問的權(quán)限范圍消痛, 可以是 public、protected祭示、private 甚至可以省略 肄满,其中 public 表示該方法可以被其他任何代碼調(diào)用,其他幾種修飾符的使用我們會在后面章節(jié)中詳細(xì)講解质涛。
(2) 返回值類型:方法返回值的類型稠歉,如果方法不返回任何值,則返回值類型指定為 void (代表無類型)汇陆;如果方法具有返回值怒炸,則需要指定返回值的類型,并且在方法體中使用 return 語句返回值毡代。
(3) 方法名:是方法的名字阅羹,必須使用合法的標(biāo)識符。
(4)參數(shù)列表:是傳遞給方法的參數(shù)列表教寂,參數(shù)可以有多個捏鱼,多個參數(shù)間以逗號隔開,每個參數(shù)由參數(shù)類型和參數(shù)名組成酪耕,以空格隔開导梆。當(dāng)方法被調(diào)用時,傳遞值給參數(shù)。這個值被稱為實參或變量看尼。參數(shù)列表是指方法的參數(shù)類型递鹉、順序和參數(shù)的個數(shù)。參數(shù)是可選的藏斩,方法可以不包含任何參數(shù)躏结。
(5)方法體:方法體包含具體的語句,定義該方法的功能狰域。
根據(jù)方法是否帶參媳拴、是否帶返回值,可將方法分為四類:
無參無返回值方法
無參帶返回值方法
帶參無返回值方法
帶參帶返回值方法
在進(jìn)行方法重載的時候需要遵循以下的規(guī)則:
- 在使用方法重載的時候北专,必須通過方法中不同的參數(shù)列表來實現(xiàn)方法的重載禀挫。如:方法的參數(shù)個數(shù)不同或者方法的參數(shù)類型不同。
- 不能通過訪問權(quán)限拓颓,返回值類型和拋出的異常來實現(xiàn)重載
- 重載的方法中允許拋出不同的異常
- 可以有不同的返回值類型语婴,只要方法的參數(shù)列表不同即可
- 可以有不同的訪問修飾符
注意:
1. 如果方法的返回類型為 void ,則方法中不能使用 return 返回值驶睦。
2. 方法的返回值最多只能有一個砰左,不能返回多個值。
3. 方法返回值的類型必須兼容场航,也就是說如果返回值類型為 int 缠导,則不能返回 String 型值。
4. 調(diào)用帶返回值的方法時溉痢,由于方法執(zhí)行后會返回一個結(jié)果僻造,因此在調(diào)用帶返回值方法時一般都會接收其返回值并進(jìn)行處理。
在java中重載方法有兩種方式:
- 通過改變參數(shù)的數(shù)量
- 通過更改數(shù)據(jù)類型
12. 面向?qū)ο螅?類和對象知識已會)
變量
一個類可以包含以下類型變量:
- 局部變量:在方法孩饼、構(gòu)造方法或者語句塊中定義的變量被稱為局部變量髓削。變量聲明和初始化都是在方法中,方法結(jié)束后镀娶,變量就會自動銷毀立膛。
- 成員變量:成員變量是定義在類中,方法體之外的變量梯码。這種變量在創(chuàng)建對象的時候?qū)嵗Ρ谩3蓡T變量可以被類中方法、構(gòu)造方法和特定類的語句塊訪問轩娶。
- 類變量:也叫靜態(tài)變量儿奶,類變量也聲明在類中,方法體之外鳄抒,但必須聲明為static類型廓握。
注意
1. 局部變量的作用域僅限于定義它的方法內(nèi)搅窿。而成員變量的作用域在整個類內(nèi)部都是可見的。
2. 同時在相同的方法中隙券,不能有同名的局部變量;在不同的方法中闹司,可以有同名的局部變量娱仔。
3. 成員變量和局部變量同名時,局部變量具有更高的優(yōu)先級游桩。
構(gòu)造方法
每個類都有構(gòu)造方法牲迫。如果沒有顯式地為類定義構(gòu)造方法,Java編譯器將會為該類提供一個默認(rèn)構(gòu)造方法借卧。
在創(chuàng)建一個對象的時候盹憎,至少要調(diào)用一個構(gòu)造方法。構(gòu)造方法的名稱必須與類同名铐刘,一個類可以有多個構(gòu)造方法陪每。
new后面跟的并是構(gòu)造方法,new + 構(gòu)造方法可以創(chuàng)建一個新的對象。
1镰吵、構(gòu)造方法的名稱與類名相同檩禾,且沒有返回值
2、如果我們在定義類的時候沒有寫構(gòu)造方法疤祭,系統(tǒng)會默認(rèn)給我們生成一個無參構(gòu)造方法盼产,不過這個構(gòu)造方法什么也不會做。
3勺馆、當(dāng)有指定的構(gòu)造方法時戏售,系統(tǒng)都不會再為我們添加無參構(gòu)造方法了。
4草穆、構(gòu)造方法的重載:方法名相同灌灾,但參數(shù)不同的多個方法,調(diào)用時會自動根據(jù)不同的參數(shù)選擇相應(yīng)的方法续挟。
包
為了更好地組織類紧卒,Java 提供了包機制,用于區(qū)別類名的命名空間诗祸。
包的作用?
- 把功能相似或相關(guān)的類或接口組織在同一個包中跑芳,方便類的查找和使用。
- 包采用了樹形目錄的存儲方式直颅。同一個包中的類名字是不同的博个,不同的包中的類的名字是可以相同的,當(dāng)同時調(diào)用兩個不同包中相同類名的類時功偿,應(yīng)該加上包名加以區(qū)別盆佣。
- 包也限定了訪問權(quán)限往堡,擁有包訪問權(quán)限的類才能訪問某個包中的類。
如何定義一個包共耍?
用package關(guān)鍵字虑灰,加上我們的包名。
如何在不同包中使用另一個包中的類?
用到import
關(guān)鍵字: import com.shiyanlou.People
同時如果import com.shiyanlou.*
: 這是將包下的所有文件都導(dǎo)入進(jìn)來痹兜,*是通配符穆咐。
注意
包的命名規(guī)范是: 全小寫字母拼寫
面向?qū)ο笥腥筇匦裕骸》庋b, 繼承字旭, 多態(tài)
13. java封裝
什么是封裝对湃?
封裝就是把代碼的實現(xiàn)細(xì)節(jié)部分包裝起來, 防止該部分代碼或者數(shù)據(jù)被外部隨機訪問.可以認(rèn)為是一個保護(hù)屏障.
為什么要這么做遗淳?
1.只能通過規(guī)定的方法訪問數(shù)據(jù).
2.可以隱藏類的實現(xiàn)細(xì)節(jié)拍柒,提高安全性
如何實現(xiàn)封裝?
1.修改屬性的可見性屈暗,在屬性的前面添加修飾符(private)`
2.對每個值屬性提供對外的公共方法訪問拆讯,如創(chuàng)建 getter/setter(取值和賦值) 方法,用于對私有屬性的訪問
3.在 getter/setter 方法里加入屬性的控制語句恐锦,例如我們可以加一個判斷語句往果,對于非法輸入給予否定。
訪問修飾符
訪問修飾符可以用來修飾屬性和方法的訪問范圍一铅。
解釋:
- private修飾的屬性或者方法陕贮,只能在當(dāng)前類中訪問或者使用。
- 默認(rèn)是什么修飾符都不加潘飘,默認(rèn)在當(dāng)前類中和同一包下都可以訪問和使用肮之。
- protected修飾的屬性或者方法,對同一包內(nèi)的類和所有子類可.
- public修飾的屬性或者方法卜录,對所有類可見戈擒。
example:
package com.shiyanlou;
public class People {
//屬性(成員變量)有什么,前面添加了訪問修飾符private
//變成了私有屬性艰毒,必須通過方法調(diào)用
private double height; //身高
//屬性已經(jīng)封裝好了筐高,如果用戶需要調(diào)用屬性
//必須用getter和setter方法進(jìn)行調(diào)用
//getter和setter方法需要程序員自己定義
public double getHeight(){
//getter 方法命名是get關(guān)鍵字加屬性名(屬性名首字母大寫)
//getter 方法一般是為了得到屬性值
return height;
}
//同理設(shè)置我們的setter方法
//setter 方法命名是set關(guān)鍵字加屬性名(首字母大寫)
//setter 方法一般是給屬性值賦值,所以有一個參數(shù)
public void setHeight(double newHeight){
height = newHeight;
}
}
然后在我們的 main 函數(shù)里的對象丑瞧,不能再直接調(diào)用屬性了柑土,只能通過getter和setter方法進(jìn)行調(diào)用。
package com.shiyanlou;
public class NewObject {
public static void main(String[] args) {
People LiLei = new People(); //創(chuàng)建了一個People對象LiLei
//利用setter方法為屬性賦值
LiLei.setHeight(170.0);
//利用getter方法取屬性值
System.out.println("LiLei的身高是"+LiLei.getHeight());
}
}
成員內(nèi)部類
package com.shiyanlou;
//外部類People
public class People {
private String name = "LiLei"; //外部類的私有屬性
//內(nèi)部類Student
public class Student {
String ID = "20151234"; //內(nèi)部類的成員屬性
//內(nèi)部類的方法
public void stuInfo(){
System.out.println("訪問外部類中的name:" + name);
System.out.println("訪問內(nèi)部類中的ID:" + ID);
}
}
//測試成員內(nèi)部類
public static void main(String[] args) {
People a = new People(); //創(chuàng)建外部類對象绊汹,對象名為a
Student b = a.new Student(); //使用外部類對象創(chuàng)建內(nèi)部類對象稽屏,對象名為b
// 或者為 People.Student b = a.new Student();
b.stuInfo(); //調(diào)用內(nèi)部對象的suInfo方法
}
}
由此,我們可以知道西乖,成員內(nèi)部類的使用方法:
Student 類相當(dāng)于 People 類的一個成員變量狐榔,所以 Student 類可以使用任意訪問修飾符
Student 類在 People 類里坛增,所以訪問范圍在類里的所有方法均可以訪問 People 的屬性(即內(nèi)部類里可以直接訪問外部類的方法和屬性,反之不行)
定義成員內(nèi)部類后薄腻,必須使用外部類對象來創(chuàng)建內(nèi)部類對象收捣,即 內(nèi)部類 對象名 = 外部類對象.new 內(nèi)部類();
如果外部類和內(nèi)部類具有相同的成員變量或方法,內(nèi)部類默認(rèn)訪問自
己的成員變量或方法庵楷,如果要訪問外部類的成員變量坏晦,可以使用 this 關(guān)鍵字.如:a.this
注:成員內(nèi)部類不能含有static的變量和方法,因為成員內(nèi)部類需要先創(chuàng)建了外部類嫁乘,才能創(chuàng)建
它自己的。
14. 繼承
為什么需要繼承?
減少重復(fù)代碼,實現(xiàn)復(fù)用
繼承的特點?
- 子類擁有父類除private以外的所有屬性和方法
- 子類可以擁有自己的屬性和方法
- 子類可以重寫實現(xiàn)父類的方法
- Java 中的繼承是單繼承球碉,一個類只有一個父類
注:
Java 實現(xiàn)多繼承的一個辦法是 implements(實現(xiàn))接口
方法的重寫
重寫的方法一定要與原父類的方法語法保持一致,比如:
返回值類型
參數(shù)類型及個數(shù)
方法名都必須一致蜓斧。
繼承的初始化順序
程序運行的過程中,是先為父類進(jìn)行初始化睁冬,還是先調(diào)用的子類進(jìn)行初始化的呢挎春?
繼承的初始化順序是先初始化父類再初始化子類。
我們根據(jù)代碼來驗證一下豆拨。
由此可知直奋,系統(tǒng)先創(chuàng)建了父類對象,再創(chuàng)建了子類對象施禾,先初始化了屬性脚线,再調(diào)用了構(gòu)造函數(shù)。
注意
final 修飾類弥搞,則該類不允許被繼承邮绿,為最終類
15.Java 多態(tài)
Java中多態(tài)的實現(xiàn)方式:接口實現(xiàn),繼承實現(xiàn)(對父類進(jìn)行方法重寫攀例,同一個類中進(jìn)行方法重載)船逮。
多態(tài)存在的三個必要條件:
一、要有繼承粤铭;
二挖胃、要有重寫;
三梆惯、父類引用指向子類對象(向上轉(zhuǎn)型)酱鸭。
繼承實現(xiàn)多態(tài)
向上轉(zhuǎn)型的理解
比如:Dog 類是 Animal 類的子類
如果定義了一個指向子類對象的父類引用類型,那么它能夠引用父類中定義的所有屬性和方法. 但是不能獲取只存在于子類的方法和屬性加袋。
注:不能使用一個子類的引用去指向父類的對象凛辣。
舉個繼承例子:
package com.shiyanlou;
class Animal {
//父類方法
public void bark() {
System.out.println("動物叫!");
}
}
class Dog extends Animal {
//子類重寫父類的bark方法
public void bark() {
System.out.println("汪职烧、汪扁誓、汪防泵!");
}
//子類自己的方法
public void dogType() {
System.out.println("這是什么品種的狗?");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
Animal b = new Dog();
Dog d = new Dog();
a.bark();
b.bark();
//b.dogType();
//b.dogType()編譯不通過
d.bark();
d.dogType();
}
}
在這里蝗敢,由于b是父類的引用捷泞,指向子類的對象,因此不能獲取子類的方法(dogType()方法),同時當(dāng)調(diào)用bark()方法時寿谴,由于子類重寫了父類的bark()方法,所以調(diào)用子類中的bark()方法锁右。
因此,向上轉(zhuǎn)型讶泰,在運行時咏瑟,會遺忘子類對象中與父類對象中不同的方法,也會覆蓋與父類中相同的方法——重寫痪署。(方法名码泞,參數(shù)都相同)
接口實現(xiàn)繼承
interface
關(guān)鍵字定義接口,它會產(chǎn)生一個完全抽象類狼犯,根本沒有提供任何方法體余寥。
多繼承實現(xiàn)方式:
實現(xiàn)上面的接口:
注意點:
- 接口不能用于實例化對象
- 接口中所有的方法是抽象方法
- 接口成員是 static final 類型
- 接口支持多繼承
abstract: 抽象類和抽象方法
Java提供了一個叫做抽象方法的機制,這種方法是不完整的悯森,僅有聲明而沒有方法體宋舷。而包含抽象方法的類叫做抽象類,抽象類在定義類時瓢姻,前面會加abstract關(guān)鍵字祝蝠。
那我們什么時候會用到抽象類呢?
在某些情況下汹来,某個父類只是知道其子類應(yīng)該包含怎樣的方法续膳,但無法準(zhǔn)確知道這些子類如何實現(xiàn)這些方法。也就是說抽象類是約束子類必須要實現(xiàn)哪些方法收班,而并不關(guān)注方法如何去實現(xiàn)坟岔。
從多個具有相同特征的類中抽象出一個抽象類,以這個抽象類作為子類的模板摔桦,從而避免了子類設(shè)計的隨意性社付。
那抽象類如何用代碼實現(xiàn)呢,它的規(guī)則如下:
- 用 abstract 修飾符定義抽象類
- 用 abstract 修飾符定義抽象方法邻耕,只用聲明鸥咖,不需要實現(xiàn)
- 包含抽象方法的類就是抽象類
- 抽象類中可以包含普通的方法,也可以沒有抽象方法
- 抽象類的對象不能直接創(chuàng)建兄世,我們通常是定義引用變量指向子類對象啼辣。
舉個抽象類的例子
package com.shiyanlou;
//抽象方法
public abstract class TelePhone {
public abstract void call(); //抽象方法,打電話
public abstract void message(); //抽象方法,發(fā)短信
}
構(gòu)建子類御滩,并實現(xiàn)抽象方法鸥拧。
package com.shiyanlou;
public class CellPhone extends TelePhone {
@Override
public void call() {
// TODO Auto-generated method stub
System.out.println("我可以打電話党远!");
}
@Override
public void message() {
// TODO Auto-generated method stub
System.out.println("我可以發(fā)短信!");
}
public static void main(String[] args) {
CellPhone cp = new CellPhone();
cp.call();
cp.message();
}
}
static
1.聲明為static的變量實質(zhì)上就是全局變量(靜態(tài)變量=類變量),當(dāng)聲明一個對象時富弦,并不產(chǎn)生static變量的拷貝沟娱,而是該類所有的實例變量共用同一個static變量。
訪問語法:
類名.靜態(tài)變量名
通常在以下兩個功能時使用靜態(tài)變量:
- 在對象之間共享值時
- 方便訪問變量時
2. 用static修飾的方法腕柜,叫做靜態(tài)方法---可以直接通過類名來訪問济似,訪問語法為:
類名.靜態(tài)方法名(參數(shù)列表...)
靜態(tài)方法有以下幾個限制:
- 它們僅能調(diào)用其他的static 方法。
- 它們只能訪問static數(shù)據(jù)盏缤。
- 它們不能以任何方式引用this 或super砰蠢。
總之:類的實例可以通過類名直接訪問所有的 靜態(tài)變量
和 靜態(tài)方法
.
final
final關(guān)鍵字可以修飾類、方法唉铜、屬性和變量
- final 修飾類娩脾,則該類不允許被繼承,為最終類
- final 修飾方法打毛,則該方法不允許被覆蓋(重寫)
- final 修飾屬性:則該類的屬性不會進(jìn)行隱式的初始化(類的初始化屬性必須有值)或在構(gòu)造方法中賦值(但只能選其一)
- final 修飾變量,則該變量的值只能賦一次值俩功,即變?yōu)?strong>常量
super
super關(guān)鍵字在子類內(nèi)部使用幻枉,代表父類對象。
訪問父類的屬性 super.屬性名
訪問父類的方法 super.bark()
子類構(gòu)造方法需要調(diào)用父類的構(gòu)造方法時诡蜓,在子類的構(gòu)造方法體里最前面的位置:super()