一圆仔、面向?qū)ο?/h2>
什么是面向?qū)ο螅嫦蜻^(guò)程蔫劣?
面向?qū)ο蟾嫦蜻^(guò)程都是編程的一種思想坪郭,一種思維方式
1.面向過(guò)程,比如遇到一件事脉幢,我們會(huì)想我們?cè)撛趺醋鐾嵛郑谝徊阶鍪裁吹诙鍪裁?/p>
2.面向?qū)ο螅瑯佑龅揭患孪铀桑覀儠?huì)想讓誰(shuí)做沪曙,
二、抽象
抽象--主要是用來(lái)將客觀世界上真實(shí)存在的事物用編程語(yǔ)言描述出來(lái)
當(dāng)編寫一個(gè)類時(shí)萎羔,我們往往會(huì)為該類定義一些方法液走,這些方法是用來(lái)描述該類的功能具體實(shí)現(xiàn)方式,那么這些方法都有具體的方法體。但是有的時(shí)候缘眶,某個(gè)父類只是知道子類應(yīng)該包含怎么樣的方法嘱根,但是無(wú)法準(zhǔn)確知道子類如何實(shí)現(xiàn)這些方法。比如一個(gè)圖形類應(yīng)該有一個(gè)求周長(zhǎng)的方法巷懈,但是不同的圖形求周長(zhǎng)的算法不一樣该抒。那該怎么辦呢?分析事物時(shí)顶燕,發(fā)現(xiàn)了共性內(nèi)容凑保,就出現(xiàn)向上抽取。會(huì)有這樣一種特殊情況涌攻,就是方法功能聲明相同愉适,但方法功能主體不同。那么這時(shí)也可以抽取癣漆,但只抽取方法聲明维咸,不抽取方法主體。那么此方法就是一個(gè)抽象方法惠爽。
描述JavaEE工程師:行為:工作癌蓖。
描述Android工程師:行為:工作。
JavaEE工程師和Android工程師之間有共性婚肆,可以進(jìn)行向上抽取租副。抽取它們的所屬共性類型:研發(fā)部員工。由于JavaEE工程師和Android工程師都具有工作功能较性,但是他們具體工作內(nèi)容卻不一樣用僧。這時(shí)在描述研發(fā)部員工時(shí),發(fā)現(xiàn)了有些功能(工作)不具體赞咙,這些不具體的功能责循,需要在類中標(biāo)識(shí)出來(lái),通過(guò)java中的關(guān)鍵字abstract(抽象)攀操。
當(dāng)定義了抽象函數(shù)的類也必須被abstract關(guān)鍵字修飾院仿,被abstract關(guān)鍵字修飾的類是抽象類
abstract class Developer {
??? public abstract void work();//抽象函數(shù)。需要abstract修飾速和,并分號(hào);結(jié)束
}
class JavaEE extendsDeveloper{??????????? //javaee工程師
??? public void work() {
??? ??? System.out.println("正在研發(fā)淘寶網(wǎng)站");
??? }
}
class Android extendsDeveloper {??? //Android工程師
??? public void work() {
??? ??? System.out.println("正在研發(fā)淘寶手機(jī)客戶端軟件");
??? }
}
抽象類的特點(diǎn):
1歹垫、抽象類和抽象方法都需要被abstract修飾。抽象方法一定要定義在抽象類中颠放。
2排惨、抽象類不可以直接創(chuàng)建對(duì)象,原因:調(diào)用抽象方法沒(méi)有意義碰凶。
3暮芭、只有覆蓋了抽象類中所有的抽象方法后鹿驼,其子類才可以創(chuàng)建對(duì)象。否則該子類還是一個(gè)抽象類谴麦。
之所以繼承抽象類蠢沿,更多的是在思想伸头,是面對(duì)共性類型操作會(huì)更簡(jiǎn)單
抽象類一定是個(gè)父類匾效????????
?????? 是的,因?yàn)椴粩喑槿《鴣?lái)的恤磷。
2面哼、抽象類中是否可以不定義抽象方法。
??????? 是可以的扫步,那這個(gè)抽象類的存在到底有什么意義呢魔策?不讓該類創(chuàng)建對(duì)象,方法可以直接讓子類去使用
3、抽象關(guān)鍵字abstract不可以和哪些關(guān)鍵字共存河胎???????
?????? private:私有的方法子類是無(wú)法繼承到的闯袒,也不存在覆蓋,而abstract和private一起使用修飾方法游岳,abstract既要子類去實(shí)現(xiàn)這個(gè)方法政敢,而private修飾子類根本無(wú)法得到父類這個(gè)方法∨咂龋互相矛盾,final跟static
三喷户、類
類描述了對(duì)象的屬性跟方法的行為,類是對(duì)象的模板和圖紙访锻,對(duì)象是類的一個(gè)實(shí)例褪尝,類是對(duì)象的模板,由對(duì)象可以抽象出類期犬,如狗類都有鼻子眼睛(屬性/變量)河哑,都會(huì)奔跑(方法/行為),由對(duì)象可以抽象出一類的事物龟虎,狗就是對(duì)象灾馒,類可以創(chuàng)建對(duì)象,用代碼實(shí)現(xiàn)遣总,狗類 狗=new 狗類();創(chuàng)建的對(duì)象會(huì)在堆內(nèi)存生成一個(gè)對(duì)象區(qū)域睬罗,區(qū)域里有屬性跟方法
public static void 狗類{
String eyes;
void run{
?? System.out.print("奔跑");
?? }
}
局部變量跟成員變量區(qū)別
區(qū)別一:定義的位置不同
定義在類中的變量是成員變量
定義在方法中或者{}語(yǔ)句里面的變量是局部變量
區(qū)別二:在內(nèi)存中的位置不同
成員變量存儲(chǔ)在對(duì)內(nèi)存的對(duì)象中
局部變量存儲(chǔ)在棧內(nèi)存的方法中
區(qū)別三:聲明周期不同
成員變量隨著對(duì)象的出現(xiàn)而出現(xiàn)在堆中,隨著對(duì)象的消失而從堆中消失
局部變量隨著方法的運(yùn)行而出現(xiàn)在棧中旭斥,隨著方法的彈棧而消失
區(qū)別四:初始化不同
成員變量因?yàn)樵诙褍?nèi)存中容达,所有默認(rèn)的初始化值
局部變量沒(méi)有默認(rèn)的初始化值,必須手動(dòng)的給其賦值才可以使用垂券。
注意:如果成員變量跟局部變量同名花盐,可以用this.成員變量來(lái)區(qū)分
四羡滑、封裝
前面我們學(xué)習(xí)方法時(shí),就提起過(guò)算芯,將具體功能封裝到方法中柒昏,學(xué)習(xí)對(duì)象時(shí),也提過(guò)將方法封裝在類中熙揍,其實(shí)這些都是封裝职祷。封裝,它也是面向?qū)ο笏枷氲奶卣髦唤烨簟C嫦驅(qū)ο蠊灿腥齻€(gè)特征:封裝有梆,繼承,多態(tài)
對(duì)象封裝--對(duì)象同時(shí)具有屬性跟方法意系,通常被封裝在一起不可分割泥耀,相輔相成,
機(jī)箱舉例:一臺(tái)電腦蛔添,它是由CPU痰催、主板、顯卡迎瞧、內(nèi)存夸溶、硬盤、電源等部件組長(zhǎng)夹攒,其實(shí)我們將這些部件組裝在一起就可以使用電腦了蜘醋,但是發(fā)現(xiàn)這些部件都散落在外面,很容造成不安全因素咏尝,于是压语,使用機(jī)箱殼子,把這些部件都裝在里面编检,并在機(jī)箱殼上留下一些插口等胎食,封裝就是保護(hù)內(nèi)部信息,人們能用就行允懂。
但是封裝完機(jī)箱是不是每個(gè)人都能打開(kāi)訪問(wèn)內(nèi)部邏輯呢厕怜,顯然只有維修人員跟后臺(tái)開(kāi)發(fā)人員可以,所以就有了權(quán)限的問(wèn)題蕾总,例如private私有權(quán)限粥航,那外部的usb接口是不是每個(gè)人都可以用啊,所以就有public公有權(quán)限
四種訪問(wèn)權(quán)限
五生百、繼承
繼承一般是子女可繼承父的財(cái)產(chǎn)递雀,在程序中同樣實(shí)現(xiàn)繼承可使多種事物有一定的關(guān)系,比如你爹有500萬(wàn)蚀浆,你繼承你爹的財(cái)產(chǎn)缀程,那么你就有500萬(wàn)了
在程序中一個(gè)類要繼承另一個(gè)類搜吧,需要使用extends關(guān)鍵字,格式:class 子類 extends 父類
案例:
// 定義個(gè)員工類
class Employee {
??? String name; // 定義name屬性
? ? public void work() { ? // 定義員工的工作方法
??? ??? System.out.println("盡心盡力地工作");
??? }
}
//定義研發(fā)部員工類Developer 繼承員工類Employe
class Developer extendsEmployee {
??? // 定義一個(gè)打印name的方法
??? public void printName() {
??? ??? System.out.println("name=" + name);
??? }
}
//定義測(cè)試類
public class Example01 {
??? public static void main(String[] args) {
??? ??? Developerd= new Developer(); // 創(chuàng)建一個(gè)研發(fā)部員工類對(duì)象
??? ??? d.name= "小明"; // 為該員工類的name屬性進(jìn)行賦值
??? ??? d.printName();// 調(diào)用該員工的printName()方法
??? ??? d.work(); // 調(diào)用Developer類繼承來(lái)的work()方法
??? }
}
在上述代碼中杨凑,Developer類通過(guò)extends關(guān)鍵字繼承了Employee類滤奈,這樣Developer類便是Employee類的子類。從運(yùn)行結(jié)果不難看出撩满,子類雖然沒(méi)有定義name屬性和work()方法蜒程,但是卻能訪問(wèn)這兩個(gè)成員。這就說(shuō)明鹦牛,子類在繼承父類的時(shí)候搞糕,會(huì)自動(dòng)擁有父類的成員勇吊。
繼承的好處&注意事項(xiàng)
繼承的好處:
1曼追、繼承的出現(xiàn)提高了代碼的復(fù)用性,提高軟件開(kāi)發(fā)效率汉规。
2礼殊、繼承的出現(xiàn)讓類與類之間產(chǎn)生了關(guān)系,提供了多態(tài)的前提针史。
在類的繼承中晶伦,需要注意一些問(wèn)題,具體如下:
在Java中啄枕,類只支持單繼承婚陪,不允許多繼承,也就是說(shuō)一個(gè)類只能有一個(gè)直接父類频祝,例如下面這種情況是不合法的泌参。
??? class A{}
???? classB{}
???? class C extends A,B{}? // C類不可以同時(shí)繼承A類和B類
2、多個(gè)類可以繼承一個(gè)父類常空,例如下面這種情況是允許的沽一。
???? classA{}
???? class B? extends A{}
???? class C? extends A{}?? //類B和類C都可以繼承類A
3、在Java中漓糙,多層繼承是可以的铣缠,即一個(gè)類的父類可以再去繼承另外的父類,例如C類繼承自B類昆禽,而B類又可以去繼承A類蝗蛙,這時(shí),C類也可稱作A類的子類醉鳖。下面這種情況是允許的捡硅。
???? classA{}
???? class B? extends A{}?? //類B繼承類A,類B是類A的子類
???? class C? extends B{}?? //類C繼承類B辐棒,類C是類B的子類病曾,同時(shí)也是類A的子類
4牍蜂、在Java中,子類和父類是一種相對(duì)概念泰涂,也就是說(shuō)一個(gè)類是某個(gè)類父類的同時(shí)鲫竞,也可以是另一個(gè)類的子類。例如上面的這種情況中逼蒙,B類是A類的子類从绘,同時(shí)又是C類的父類。
繼承-子父類中成員變量的特點(diǎn)
了解了繼承給我們帶來(lái)的好處是牢,提高了代碼的復(fù)用性僵井。繼承讓類與類或者說(shuō)對(duì)象與對(duì)象之間產(chǎn)生了關(guān)系。那么驳棱,當(dāng)繼承出現(xiàn)后批什,類的成員之間產(chǎn)生了那些變化呢?
類的成員重點(diǎn)學(xué)習(xí)成員變量社搅、成員方法的變化驻债。
成員變量:如果子類父類中出現(xiàn)不同名的成員變量,這時(shí)的訪問(wèn)是沒(méi)有任何問(wèn)題形葬。
看如下代碼:
class Fu{
??? int num = 5;? //Fu中的成員變量合呐。
}
class Zi extends Fu{
??? int num2 = 6;?? //Zi中的成員變量
??? publicvoid show()??? ? //Zi中的成員方法
??? {
??? ??? System.out.println("Funum="+num);????? ? //訪問(wèn)父類中的num?
??? ??? System.out.println("Zinum2="+num2);???? //訪問(wèn)子類中的num2
??? }
}
class Demo{
??? publicstatic void main(String[] args){
??? ??? Zi z = new Zi(); //創(chuàng)建子類對(duì)象
??? ??? z.show(); //調(diào)用子類中的show方法
??? }
}
代碼說(shuō)明:Fu類中的成員變量是非私有的,子類中可以直接訪問(wèn)笙以,若Fu類中的成員變量私有了淌实,子類是不能直接訪問(wèn)的。
當(dāng)子父類中出現(xiàn)了同名成員變量時(shí)猖腕,在子類中若要訪問(wèn)父類中的成員變量拆祈,必須使用關(guān)鍵字super來(lái)完成。super用來(lái)表示當(dāng)前對(duì)象中包含的父類對(duì)象空間的引用谈息。super今天不做具體講解缘屹,在課程第12天會(huì)詳細(xì)講解。
在子類中侠仇,訪問(wèn)父類中的成員變量格式:
super.父類中的成員變量
看如下代碼:
class Fu{
??? int num = 5;????????? //Fu中的成員變量轻姿。
}
class Zi extends Fu{
??? int num = 6;???? //Zi中的成員變量
??? voidshow() {
??? ??? //子父類中出現(xiàn)了同名的成員變量時(shí)
??? ??? //在子類中需要訪問(wèn)父類中非私有成員變量時(shí),需要使用super關(guān)鍵字
??? ??? //訪問(wèn)父類中的num
??? ??? System.out.println("Fu num="+super.num);
??? ??? //訪問(wèn)子類中的num2
??? ??? System.out.println("Zi num2="+this.num);
??? }
}
class Demo5{
??? publicstatic void main(String[] args){
??? ??? Zi z = new Zi(); //創(chuàng)建子類對(duì)象
??? ??? z.show(); //調(diào)用子類中的show方法
??? }
}
繼承-子父類中成員方法特點(diǎn)-重寫&應(yīng)用
子父類中成員方法的特點(diǎn)
當(dāng)在程序中通過(guò)對(duì)象調(diào)用方法時(shí)逻炊,會(huì)先在子類中查找有沒(méi)有對(duì)應(yīng)的方法互亮,若子類中存在就會(huì)執(zhí)行子類中的方法,若子類中不存在就會(huì)執(zhí)行父類中相應(yīng)的方法余素。
看如下代碼:
class Fu{
??? publicvoid show(){
??? ??? System.out.println("Fu類中的show方法執(zhí)行");
??? }
}
class Zi extends Fu{
??? publicvoid show2(){
??? ??? System.out.println("Zi類中的show2方法執(zhí)行");
??? }
}
public? classTest{
??? publicstatic void main(String[] args) {
??? ??? Zi z = new Zi();
??? ??? z.show(); //子類中沒(méi)有show方法豹休,但是可以找到父類方法去執(zhí)行
??? ??? z.show2();
??? }
}
成員方法特殊情況——覆蓋
子類中出現(xiàn)與父類一模一樣的方法時(shí),會(huì)出現(xiàn)覆蓋操作桨吊,也稱為override重寫威根、復(fù)寫或者覆蓋凤巨。
class Fu{
??? public void show() {
??? ??? System.out.println("Fu show");
??? }
}
class Zi extends Fu{
?? public? void show()????? //子類復(fù)寫了父類的show方法
??? {
??? ??? System.out.println("Zi show");
??? }
}
方法重寫(覆蓋)的應(yīng)用:
當(dāng)子類需要父類的功能,而功能主體子類有自己特有內(nèi)容時(shí)洛搀,可以重寫父類中的方法敢茁,這樣,即沿襲了父類的功能留美,又定義了子類特有的內(nèi)容彰檬。
舉例:比如手機(jī),當(dāng)描述一個(gè)手機(jī)時(shí)谎砾,它具有發(fā)短信逢倍,打電話,顯示來(lái)電號(hào)碼功能景图,后期由于手機(jī)需要在來(lái)電顯示功能中增加顯示姓名和頭像较雕,這時(shí)可以重新定義一個(gè)類描述智能手機(jī),并繼承原有描述手機(jī)的類症歇。并在新定義的類中覆蓋來(lái)電顯示功能郎笆,在其中增加顯示姓名和頭像功能谭梗。
在子類中忘晤,訪問(wèn)父類中的成員方法格式:
super.父類中的成員方法();
看如下代碼:
public class Test {
??? publicstatic void main(String[] args) {
??? ??? new NewPhone().showNum();
??? }
}
class Phone{???????? //手機(jī)類
??? publicvoid sendMessage(){
??? ??? System.out.println("發(fā)短信");
??? }
??? publicvoid call(){
??? ??? System.out.println("打電話");
??? }
??? public void showNum(){
??? ??? System.out.println("來(lái)電顯示號(hào)碼");
??? }
}
class NewPhone extends Phone{??????? //智能手機(jī)類
??? public void showNum(){?????????? ? //覆蓋父類的來(lái)電顯示號(hào)碼功能,并增加自己的顯示姓名和圖片功能
??? ??? super.showNum();??????? ? //調(diào)用父類已經(jīng)存在的功能使用super
??? ??? System.out.println("顯示來(lái)電姓名");?????????? ?? //增加自己特有顯示姓名和圖片功能
??? ??? System.out.println("顯示頭像");
??? }
}
方法重寫的注意事項(xiàng)
重寫需要注意的細(xì)節(jié)問(wèn)題:
子類方法覆蓋父類方法激捏,必須要保證權(quán)限大于等于父類權(quán)限设塔。
class Fu(){
void show(){}
??? publicvoid method(){}
}
class Zi() extends Fu{
public void show(){}? //編譯運(yùn)行沒(méi)問(wèn)題
??? voidmethod(){}????? //編譯錯(cuò)誤
}
寫法上稍微注意:必須一模一樣:方法的返回值類型 方法名 參數(shù)列表都要一樣。
總結(jié):當(dāng)一個(gè)類是另一個(gè)類中的一種時(shí)远舅,可以通過(guò)繼承闰蛔,來(lái)繼承屬性與功能。如果父類具備的功能內(nèi)容需要子類特殊定義時(shí)图柏,進(jìn)行方法重寫序六。