本章內(nèi)容
類的繼承
理解繼承的含義在Java中定義一個(gè)類時(shí)诬垂,讓該類通過(guò)關(guān)鍵字extends繼承一個(gè)已有的類稚机,這就是類的繼承(泛化)。
被繼承的類稱為父類(超類侮繁,基類),新的類稱為子類(派生類)如孝。
子類繼承父類的所有屬性和方法宪哩,同時(shí)也可以增加自己的屬性和方法。
ava中只能單繼承第晰,也就是說(shuō)每個(gè)類只能有一個(gè)直接父類锁孟;一個(gè)父類可以有多個(gè)子類彬祖。
其實(shí),在繼承關(guān)系中我們還能發(fā)現(xiàn)一個(gè)規(guī)律:子類是父類的一種品抽,也可以說(shuō)“子類就是父類”储笑。如:人類就是動(dòng)物,動(dòng)物就是生物圆恤。記住這個(gè)定律對(duì)我們理解繼承的概念非常有幫助突倍。但是,反過(guò)來(lái)看盆昙,父類是子類的說(shuō)法正確嗎羽历?
繼承的語(yǔ)法和規(guī)則
示例 Employee.java Worker.java
[修飾符]class子類名extends父類名
? 練習(xí) Officer.java TestOfficer.java
用java中類的繼承機(jī)制,實(shí)現(xiàn)Officer類淡喜,并設(shè)計(jì)一個(gè)測(cè)試程序TestOfficer類秕磷,來(lái)訪問(wèn)Officer類
繼承的好處
子類實(shí)例化的過(guò)程
子類實(shí)例化時(shí)先實(shí)例化其父類,然后實(shí)例化子類炼团。
要先調(diào)用父類的構(gòu)造器澎嚣,父類構(gòu)造器運(yùn)行完畢,才調(diào)用子類的構(gòu)造器瘟芝。
如果實(shí)例化類D易桃,說(shuō)出構(gòu)造器執(zhí)行的順序。
super和this關(guān)鍵字
super()
this()
作用:調(diào)用本類的構(gòu)造器
只能寫在構(gòu)造器的第一行
在同一個(gè)構(gòu)造器中super()和this()不能同時(shí)出現(xiàn)
子類實(shí)例化的過(guò)程
使用默認(rèn)的構(gòu)造器
在子類中的創(chuàng)建構(gòu)造器 示例 Worker.java
在子類中創(chuàng)建構(gòu)造器時(shí)模狭,必須調(diào)用父類的構(gòu)造器
子類可以在自己的構(gòu)造器中使用super關(guān)鍵字來(lái)調(diào)用父類的構(gòu)造器
super(參數(shù)1颈抚,參數(shù)2,…);
如果使用super關(guān)鍵字調(diào)用父類構(gòu)造器嚼鹉,必須寫在該子類構(gòu)造器的第一行
如調(diào)用的是父類中無(wú)參的構(gòu)造器贩汉,則可以不寫super( )
如果子類中調(diào)用了父類無(wú)參的構(gòu)造器,而父類中沒(méi) 有無(wú)參構(gòu)造器則系統(tǒng)編譯出錯(cuò)
super.
指向父類的引用锚赤。
通過(guò)關(guān)鍵字super我們可以指定子類在構(gòu)造時(shí)調(diào)用父類的哪個(gè)構(gòu)造器匹舞,達(dá)到先實(shí)例化父類然后實(shí)例化子類的目的。
子類的構(gòu)造器默認(rèn)的調(diào)用父類無(wú)參構(gòu)造器线脚,即子類構(gòu)造器中沒(méi)有用super指明調(diào)用父類哪個(gè)構(gòu)造器的話赐稽,實(shí)際上編譯器會(huì)自動(dòng)的在子類構(gòu)造器第 一行加入代碼super( );
this.
指向本類的引用。
我們知道子類在實(shí)例化時(shí)必須調(diào)用父類的構(gòu)造器浑侥,實(shí)際上有的子類構(gòu)造器
也可以先調(diào)用本類的其他構(gòu)造器姊舵,然后再通過(guò)那個(gè)構(gòu)造器調(diào)用父類的構(gòu)造器
無(wú)論是調(diào)用父類的構(gòu)造器還是子類的構(gòu)造器,最終都是找到最頂級(jí)的父類自
上而下的實(shí)例化寓落。只要中間環(huán)節(jié)有一個(gè)構(gòu)造器沒(méi)找到括丁,這個(gè)子類就無(wú)法完成實(shí)例化
給定以下代碼:
答案:A
Java包的概念
包的概念及應(yīng)用
在Java中,包主要有以下用途 :
包允許將類組合成較小的單元
有助于避免命名沖突
包允許在更廣的范圍內(nèi)保護(hù)類伶选、數(shù)據(jù)和方法
包可以是類史飞、接口和子包的集合
將類放入包中
package包名 ;
注意:
在java中位于包中的類尖昏,在文件系統(tǒng)中的存放位置,必須有與包名層次相對(duì)應(yīng)的目錄結(jié)構(gòu)
package語(yǔ)句作為java源文件的第一條語(yǔ)句
每個(gè)源文件只能聲明一個(gè)包
如果沒(méi)有package語(yǔ)句构资,則默認(rèn)為無(wú)名包
Java類庫(kù)中常用的包
java.lang
Java語(yǔ)言包抽诉,任何程序中,該包都被自動(dòng)導(dǎo)入吐绵。
java.awt
圖形用戶界面包
java.awt.event
圖形用戶界面事件處理包迹淌。
java.swing
跨平臺(tái)輕量級(jí)組件包。
java.sql
數(shù)據(jù)庫(kù)訪問(wèn)包拦赠。
java.io
這個(gè)包由對(duì)您的輸入/輸出操作有用的類組成巍沙。
java.util
該包提供了許多創(chuàng)建如:lists, calendar, date等所需要的類和接口。
java.net
該包提供了許多進(jìn)行TCP/IP網(wǎng)絡(luò)編程的類和接口荷鼠。
import導(dǎo)入包中的類
包名.路徑名
package test;
class Cat extends p08.Animal{…}
使用import關(guān)鍵字引入其它包中的類
package test;
import p08.Animal;
class Cat extends Animal{…}
位于同一包中的類可以直接訪問(wèn)
導(dǎo)入包中所有的類
import 包名.*;
導(dǎo)入子包中所有的類
import 包名.子包名.*;
導(dǎo)入包中的某個(gè)類
import 包名.子包名.類名;
權(quán)限訪問(wèn)操作符
使用訪問(wèn)權(quán)限修飾符對(duì)類的成員進(jìn)行控制句携,在java中稱為“封裝”。
不過(guò)不要把封裝理解為private允乐,不要誤認(rèn)為不能訪問(wèn)成員才是封裝矮嫉。實(shí)際上對(duì)成員訪問(wèn)權(quán)限的任何控制(包括public)都可以稱為封裝機(jī)制。
構(gòu)造器和類的權(quán)限通常為public牍疏;private權(quán)限最小蠢笋,限制類外訪問(wèn),一般把屬性設(shè)為private鳞陨,讓其他類不能直接訪問(wèn)屬性昨寞,達(dá)到保護(hù)屬性的目的;friendly是默認(rèn)權(quán)限厦滤,即不使用權(quán)限修飾符時(shí)援岩,即為friendly,該權(quán)限聲明的成員在類內(nèi)以及在同一個(gè)包中的其他類可以訪問(wèn)掏导;而protected所修飾的成員在類內(nèi)享怀、同一個(gè)包中、所在類的子類中都可以訪問(wèn)趟咆。
public > protected > friendly > private
封裝
信息隱藏,隱藏對(duì)象的實(shí)現(xiàn)細(xì)節(jié)添瓷,不讓用戶看到
將東西包裝在一起,然后以新的完整形式呈現(xiàn)出來(lái)
例如值纱,兩種或多種化學(xué)藥品組成一個(gè)膠囊
將方法和屬性一起包裝到一個(gè)單元中鳞贷,單元以類的形式實(shí)現(xiàn)
“隱藏屬性、方法或?qū)崿F(xiàn)細(xì)節(jié)的過(guò)程稱為封裝虐唠∏幕危”
隱藏類的實(shí)現(xiàn)細(xì)節(jié)
讓使用者只能通過(guò)事先定制好的方法來(lái)訪問(wèn)數(shù)據(jù),可以方便地加入控制邏輯,限制對(duì)屬性的不合理操作
便于修改妈橄,增強(qiáng)代碼的可維護(hù)性
可進(jìn)行數(shù)據(jù)檢查
示例 Employor.java TestEmployer.java
訪問(wèn)權(quán)限修飾符
用來(lái)控制類的成員和類的使用范圍
類成員的訪問(wèn)權(quán)限修飾符:private、default翁脆、protected眷蚓、public
類的訪問(wèn)權(quán)限修飾符:public、default
方法的覆蓋
方法的覆蓋(override)
重寫(rewrite)
對(duì)從父類中繼承來(lái)的方法進(jìn)行改造
在子類繼承父類時(shí)發(fā)生方法覆蓋的規(guī)則
在子類中的覆蓋方法與父類中被覆蓋的方法應(yīng)具有相同的方法名相同的參數(shù)列表(參數(shù)數(shù)量反番、參數(shù)類型沙热、參數(shù)順序都要相同)相同的返回值類型子類覆蓋方法的訪問(wèn)權(quán)限要不小于父類中被覆蓋方法的訪問(wèn)權(quán)限示例Worker.java
引用數(shù)據(jù)類型的轉(zhuǎn)換
上溯造型
向上轉(zhuǎn)型(Upcasting)— 子類轉(zhuǎn)換為父類,自動(dòng)轉(zhuǎn)換罢缸;
前提 — 具有繼承或?qū)崿F(xiàn)關(guān)系
向上轉(zhuǎn)換損失了子類新擴(kuò)展的屬性和方法篙贸,僅可以使用從父類中繼承的屬性和方法
instanceof 運(yùn)算符
其實(shí)經(jīng)過(guò)上溯和下溯造型之后,我們很難知道某個(gè)引用到底指向哪種類型的對(duì)象了枫疆。
可以通過(guò)instanceof來(lái)判斷該經(jīng)過(guò)上溯轉(zhuǎn)型后是哪一個(gè)子類的爵川。
instanceof運(yùn)算符的一般格式:
instanceof 運(yùn)算符
判斷一個(gè)類是否實(shí)現(xiàn)了某個(gè)接口
對(duì)象 instanceof 接口
判斷一個(gè)實(shí)例對(duì)象是否屬于一個(gè)類
對(duì)象 instanceof 類
它的返回值是boolean型的
簡(jiǎn)單來(lái)說(shuō),多態(tài)是具有表現(xiàn)多種形態(tài)的能力的特征
同一個(gè)實(shí)現(xiàn)接口息楔,使用不同的實(shí)例而執(zhí)行不同操作
多態(tài)(動(dòng)態(tài)綁定寝贡、Polymorphism )
不同的對(duì)象對(duì)同一行為作出的不同響應(yīng)多態(tài)存在的三個(gè)必要條件要有繼承,或?qū)崿F(xiàn)要有重寫父類引用指向子類對(duì)象一旦滿足以上3個(gè)條件值依,當(dāng)調(diào)用父類中被重寫的方法后圃泡,運(yùn)行時(shí)創(chuàng)建的是哪個(gè)子類的對(duì)象,就調(diào)用該子類中重寫的那個(gè)方法在執(zhí)行期間(而非編譯期間)判斷所引用對(duì)象的實(shí)際類型愿险,根據(jù)其實(shí)際類型調(diào)用相應(yīng)的方法
多態(tài)的優(yōu)點(diǎn)
簡(jiǎn)化代碼
改善代碼的組織性和可讀性
易于擴(kuò)展
static關(guān)鍵字
靜態(tài)變量
所有對(duì)象共享
也稱為類變量
用static修飾的成員變量颇蜡,它們?cè)陬惐惠d入時(shí)創(chuàng)建,只要類存在辆亏,static變量就存在(參考java虛擬機(jī)視頻)
兩種方式訪問(wèn):
直接訪問(wèn):類名.屬性风秤;
實(shí)例化后訪問(wèn):對(duì)象名.屬性
靜態(tài)方法
不需要實(shí)例化,可以直接訪問(wèn)
也稱為類方法
兩種方式訪問(wèn):
直接訪問(wèn):類名.方法名()
實(shí)例化后訪問(wèn):對(duì)象名.方法名()
static方法的作用
簡(jiǎn)化方法的使用褒链;
便于訪問(wèn)靜態(tài)屬性唁情;
注意事項(xiàng)
靜態(tài)方法里只能直接訪問(wèn)靜態(tài)成員,而不能直接訪問(wèn)類中的非
靜態(tài)成員靜態(tài)方法中不能使用this甫匹、super關(guān)鍵字
靜態(tài)方法不能被非靜態(tài)方法覆蓋甸鸟,靜態(tài)方法不能修飾構(gòu)造器
靜態(tài)代碼塊
一個(gè)類中由static關(guān)鍵字修飾的,不包含在任何方法體中的代碼塊
當(dāng)類被載入時(shí)兵迅,靜態(tài)代碼塊被執(zhí)行抢韭,且只被執(zhí)行一次
靜態(tài)塊經(jīng)常用來(lái)進(jìn)行類屬性的初始化
單例模式
單例模式(singleton):保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)
單例模式要點(diǎn):
某個(gè)類只能有一個(gè)實(shí)例
它必須自行創(chuàng)建這個(gè)示例
必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例
單例模式實(shí)現(xiàn):
擁有一個(gè)私有構(gòu)造器
提供一個(gè)自身靜態(tài)私有的成員變量
提供一個(gè)公有的靜態(tài)公有的方法
final關(guān)鍵字
final可以修飾的元素:
類:不能被繼承變量(屬性和局部變量):
不能被重新賦值在聲明時(shí)賦值恍箭,或在構(gòu)造器中賦值系統(tǒng)不會(huì)對(duì)final屬性默認(rèn)的賦初始值
方法:不能在子類中被覆蓋刻恭,即不能修改。
TestFinal.java在程序中經(jīng)常使用的一些常量,如圓周率鳍贾,沒(méi)必要在程序中頻繁的修改它那么我們可以:首先把它設(shè)置為靜態(tài)static鞍匾,多個(gè)實(shí)例共享該常量,沒(méi)有必要每個(gè)對(duì)象保存一份骑科;
其次橡淑,設(shè)置為final類型,賦值以后不能再改變咆爽;最后注意遵守常量命名規(guī)范梁棠,所有字母大寫、單詞之間用下劃線斗埂。
抽象類
抽象類和抽象方法的概念
抽象類是抽象方法和非抽象方法的集合
[訪問(wèn)權(quán)限修飾符] abstract class 類名{ ……}
特殊情況
全部是抽象方法
全部為非抽象方法
抽象類和抽象方法的概念
抽象方法
只有方法聲明符糊,沒(méi)有方法實(shí)現(xiàn)的方法
[訪問(wèn)權(quán)限修飾符] abstract 返回值類型 抽象方法名 (參數(shù)列表) ;
abstract class A{
abstract int method1(int a,int b);}
抽象類的規(guī)則
注意:
抽象類不能被實(shí)例化;其包含的抽象方法必須在其子類中被實(shí)現(xiàn)呛凶,否則該子類只能聲明為abstract男娄;抽象方法不能為static;
在下列情況下把兔,一個(gè)類必須聲明為抽象類:
當(dāng)一個(gè)類的一個(gè)或多個(gè)方法是抽象方法時(shí)沪伙;
當(dāng)類是一個(gè)抽象類的子類,并且沒(méi)有實(shí)現(xiàn)父類的所有抽象方法县好,即只實(shí)現(xiàn)部分围橡;
當(dāng)一個(gè)類實(shí)現(xiàn)一個(gè)接口,并且不能為全部抽象方法都提供實(shí)現(xiàn)時(shí)缕贡;
接 口(interface)
接口的概念 示例 AudioDevice.java VideoDevice.java
接口中只包含常量和抽象方法翁授,而沒(méi)有變量和方法的實(shí)現(xiàn)
接口對(duì)類來(lái)說(shuō)是一套規(guī)范,是一套行為協(xié)議晾咪;
接口不是一個(gè)類收擦,不能實(shí)例化
接口的成員:
常量(字段)
抽象方法
注意:
接口不是一個(gè)類,沒(méi)有構(gòu)造器谍倦,不能被實(shí)例化
接口使用interface關(guān)鍵字來(lái)定義塞赂,而不是class
接口默認(rèn):
常量:public static final
抽象方法:public abstract
接口的概念
示例 VADevice.java
接口可以實(shí)現(xiàn)多繼承:
用接口可以實(shí)現(xiàn)混合類型(主類型,副類型)昼蛀,java 中可以通過(guò)接口分出主次類型
主類型使用繼承宴猾,副類型,使用接口實(shí)現(xiàn)
接口可以使方法的定義和實(shí)現(xiàn)相分離叼旋,降低模塊間或系統(tǒng)間的耦合性
針對(duì)接口編程可以屏蔽不同實(shí)現(xiàn)間的差異仇哆,看到的只是實(shí)現(xiàn)好的功能揍愁。
接口和類的關(guān)系
類實(shí)現(xiàn)接口 — implements
為了使用一個(gè)接口棕洋,你要編寫實(shí)現(xiàn)接口的類
如果一個(gè)類要實(shí)現(xiàn)一個(gè)接口,那么這個(gè)類就必須實(shí)現(xiàn)接口中所有抽象方法蜈出。否則這個(gè)類只能聲明為抽象類
多個(gè)無(wú)關(guān)的類可以實(shí)現(xiàn)一個(gè)接口,一個(gè)類可以實(shí)現(xiàn)多個(gè)無(wú)關(guān)的接口
一個(gè)類可以在繼承一個(gè)父類的同時(shí)延欠,實(shí)現(xiàn)一個(gè)或多個(gè)接口
示例 Television.java
接口和類的關(guān)系
? 示例 Student.java Consumer.java Person.java
有一個(gè)Student類該類繼承了Person類陌兑,并實(shí)現(xiàn)了Consumer接口該類具有String類型的屬性school并有一個(gè)study方法,在該方法中衫冻,系統(tǒng)可打印出學(xué)生在那所學(xué)校學(xué)習(xí)并創(chuàng)建一個(gè)測(cè)試方法诀紊,測(cè)試Student類
接口與抽象類的對(duì)比
接口不能含有任何非抽象方法,而抽象類可以隅俘。
類可以實(shí)現(xiàn)多個(gè)接口,但只能有一個(gè)父類笤喳。
接口和接口之間可以多繼承
抽象類可以理解為抽象方法和非抽象方法的混合體为居,而接口中的方法完全是抽象方法,是一套純粹的規(guī)范杀狡。一般來(lái)說(shuō)蒙畴,有關(guān)系的類才能繼承同一個(gè)抽象類,而無(wú)關(guān)的類不可能有同一個(gè)抽象父類呜象,但是無(wú)關(guān)的類可以實(shí)現(xiàn)同一個(gè)接口膳凝。
內(nèi)部類
內(nèi)部類特性
內(nèi)部類就是定義在另一個(gè)類內(nèi)部的類。
內(nèi)部類對(duì)于同一包中的其它類來(lái)說(shuō)恭陡,內(nèi)部類能夠隱藏起來(lái)蹬音。
注意
內(nèi)部類可以訪問(wèn)其外部類中所有的屬性和方法
無(wú)需創(chuàng)建外部類的對(duì)象,即可從內(nèi)部類訪問(wèn)外部類的變量和方法休玩。
必須創(chuàng)建內(nèi)部類的對(duì)象著淆,否則無(wú)法從外部類訪問(wèn)內(nèi)部類的變量和方法。
如果內(nèi)部類中有和外部類同名的變量或方法拴疤,則內(nèi)部類的變量和方法將獲得比外部類的變量和方法更高的優(yōu)先級(jí)永部。
不能定義static變量
內(nèi)部類特性
示例Outer.java
一個(gè)類只會(huì)被這個(gè)類所調(diào)用,其他類不會(huì)使用他呐矾,你可以把它定義成一內(nèi)部類苔埋,這樣可以隱藏實(shí)現(xiàn)細(xì)節(jié),避免錯(cuò)誤的調(diào)用蜒犯。
內(nèi)部類特性
普通類的訪問(wèn)權(quán)限修飾符
default
public
內(nèi)部類的訪問(wèn)權(quán)限修飾符
default
public
protected
private
示例 Outer3.java OuterTest.java
在Outer內(nèi)訪問(wèn)Inner,只需如下:
Inner in=new Inner() ;
在Outer外訪問(wèn)Inner,必須如下:
Outer o =new Outer();//實(shí)例化外部類Outer.Inner oi = o.new Inner();//實(shí)例化內(nèi)部類
靜態(tài)內(nèi)部類
用static標(biāo)識(shí)的內(nèi)部類為靜態(tài)內(nèi)部類组橄。
靜態(tài)內(nèi)部類作為外部類的靜態(tài)成員,不能訪問(wèn)外部類非靜態(tài)成員愧薛。
非靜態(tài)內(nèi)部類只能定義非靜態(tài)成員晨炕,而靜態(tài)內(nèi)部類可以定義靜態(tài)成員和非靜態(tài)成員。
使用Outer.Inner inn=new Outer.Inner()方式實(shí)例化靜態(tài)內(nèi)部類毫炉。
非靜態(tài)內(nèi)部類不可以使用上面的方式實(shí)例化瓮栗。
局部?jī)?nèi)部類
在一個(gè)類的方法體中或程序塊內(nèi)定義的內(nèi)部類
示例
在方法定義的內(nèi)部類中只能訪問(wèn)方法中的final類型的局部變量。
本章重點(diǎn)總結(jié)
類的繼承Java中的包和訪問(wèn)修飾符方法的覆蓋引用數(shù)據(jù)類型的轉(zhuǎn)換多態(tài)static關(guān)鍵字抽象類和接口final關(guān)鍵字。