国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

黑馬程序員——【Java基礎(chǔ)】——面向?qū)ο螅ㄒ唬└攀?、類與對象、繼承、抽象類、接口、多態(tài)、內(nèi)部類

2019-11-14 21:14:32
字體:
供稿:網(wǎng)友
黑馬程序員——【java基礎(chǔ)】——面向?qū)ο螅ㄒ唬└攀?、類與對象、繼承、抽象類、接口、多態(tài)、內(nèi)部類

---------- android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------

一、面向?qū)ο蟾攀?/strong>

  1、面向?qū)ο螅菏且粋€(gè)很抽象的概念,它相對面向過程而言,是一種程序設(shè)計(jì)的思想。

  2、面向?qū)ο蟮奶攸c(diǎn):

  * 符合人們思考習(xí)慣的思想

  * 可以將復(fù)雜的事情簡單化

  * 將程序員從執(zhí)行者轉(zhuǎn)換成了指揮者

  * 完成需求時(shí):只需要尋找具備所需功能的對象或者創(chuàng)建所需功能的對象即可,簡化開發(fā)效率并提高對象的復(fù)用性。

  3、面向?qū)ο蟮娜齻€(gè)特征:封裝(Encapsulation)、繼承(Inheritance)、多態(tài)(Polymorphism)。

二、類與對象

 ?。ㄒ唬╊惻c對象之間的關(guān)系

  1、類的定義:類是一組事物共有特征和功能的描述。類是對于一組事物的總體描述。Java用類class來描述對象的屬性和行為。

  2、對象:對象是類的實(shí)例,

  3、類的定義格式:

  [修飾符] class類名{

            屬性;

            構(gòu)造方法;

            一般方法;

      }

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

  成員變量:  * 成員變量定義在類中,在整個(gè)類中都可以被訪問?! ? 成員變量隨著對象的建立而建立,存在于對象所在的堆內(nèi)存中?! ? 成員變量有默認(rèn)初始化值。

  局部變量:  * 局部變量只定義在局部范圍內(nèi),如:函數(shù)內(nèi),語句內(nèi)等?! ? 局部變量存在于棧內(nèi)存中?! ? 作用的范圍結(jié)束,變量空間會(huì)自動(dòng)釋放?! ? 局部變量沒有默認(rèn)初始化值。

 ?。ㄈ?gòu)造函數(shù)

  1、特點(diǎn):

 ?。?)函數(shù)名與類名相同。

  (2)無返回值。

  2、作用:給對象進(jìn)行初始化。對象一建立就會(huì)調(diào)用與之對應(yīng)的構(gòu)造函數(shù)。

  3、構(gòu)造函數(shù)的細(xì)節(jié):

  當(dāng)一個(gè)類中沒有定義構(gòu)造函數(shù)時(shí),系統(tǒng)就會(huì)默認(rèn)給該類加入一個(gè)空參數(shù)的構(gòu)造函數(shù)。當(dāng)在類中自定義了構(gòu)造函數(shù)后,默認(rèn)的構(gòu)造函數(shù)就沒有了。

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

 ?。?)寫法上不同。

 ?。?)在運(yùn)行上也有不同:構(gòu)造函數(shù)式在對象一建立就運(yùn)行,給對象初始化。而一般方法是對象調(diào)用時(shí)才執(zhí)行,是給對象添加對象具備的功能。

 ?。?)一個(gè)對象建立,構(gòu)造函數(shù)只運(yùn)行一次。而一般方法可以被該對象調(diào)用多次。

  5、什么時(shí)候定義構(gòu)造函數(shù)?

  當(dāng)分析事物時(shí),該事物存在具備一些特性或者行為,那么將這些內(nèi)容定義在構(gòu)造函數(shù)中。

  6、構(gòu)造代碼塊

  {System.out.PRintln(“person code run”); }

  作用:給對象進(jìn)行初始化。對象一建立就運(yùn)行,而且優(yōu)先于構(gòu)造函數(shù)執(zhí)行。

  “構(gòu)造函數(shù)”與“構(gòu)造代碼塊”的區(qū)別總結(jié):(1)優(yōu)先級不同,構(gòu)造代碼塊優(yōu)先于構(gòu)造函數(shù);(2)初始化對象不同。構(gòu)造代碼塊中定義的是不同對象共性的初始化內(nèi)容,是給所有對象進(jìn)行統(tǒng)一初始化。而構(gòu)造函數(shù)是給對應(yīng)的對象初始化。

 ?。ㄋ模?/strong>this關(guān)鍵字

  1、作用:指向當(dāng)前類的屬性和方法。

  2、說明:在類定義中,如果“局部變量”和“成員變量”同名,則在將“局部變量”賦給“成員變量”時(shí),可以使用this關(guān)鍵字,例如使用方式可以使:this.name = name 。

  3、問題:this看上去好像是為了區(qū)分變量同名,即區(qū)分局部變量和成員變量。this為什么可以解決這種區(qū)分?它到底代表什么呢?

    解答:this代表本類的對象,代表它所在函數(shù)所屬的對象的引用。因?yàn)閠his持有本類對象的引用,所以this單獨(dú)使用代表當(dāng)前對象。

  4、補(bǔ)充:this也可以使用在構(gòu)造函數(shù)中調(diào)用其他的構(gòu)造函數(shù)。在構(gòu)造函數(shù)中,用this調(diào)用其他構(gòu)造函數(shù),必須寫在第一行,因?yàn)槌跏蓟葓?zhí)行。。

  5this關(guān)鍵字的基本應(yīng)用(Java代碼)

  需求:this關(guān)鍵字用于“構(gòu)造函數(shù)”間調(diào)用

1 class Person{2        Person (String name){3              this.name = name;4        }5        Person( String name , int age ){6              this( name );   //等價(jià)于 this.name = name,即調(diào)用上面的構(gòu)造函數(shù)7           this.age = age;8        }9 }

  6、關(guān)于this及構(gòu)造函數(shù)的總結(jié):

 ?。?)用于區(qū)分同名變量的情況,說的成員和局部同名的時(shí)候;

 ?。?)用于構(gòu)造函數(shù)間調(diào)用,this語句只能定義在構(gòu)造函數(shù)的第一行。

 ?。?)構(gòu)造函數(shù)之間相互調(diào)用,初始化動(dòng)作先執(zhí)行。初始化動(dòng)作中的初始化要先執(zhí)行;構(gòu)造函數(shù)自身的初始化,最后執(zhí)行。

 ?。?)注意:構(gòu)造杉樹之間的相互調(diào)用初始化,會(huì)陷入死循環(huán)。

  (五)static關(guān)鍵字

  1、static關(guān)鍵字說明

  static是一個(gè)修飾符,用于修飾成員(成員變量和成員函數(shù))。當(dāng)類成員被static修飾后,就多了一個(gè)調(diào)用方式,除了可以被對象調(diào)用外,還可以直接通過類名調(diào)用。格式:類名.靜態(tài)成員。

  2、static的特點(diǎn)

  (1)隨著類的加載而加載,隨著類的消失而消失,其生命周期最長。

  (2)優(yōu)先于對象存在。(靜態(tài)是先存在。對象是后存在)

 ?。?)被所有對象所共享。

  (4)可以直接通過類名所調(diào)用。

 ?。?)static修飾的數(shù)據(jù)是共享數(shù)據(jù)。由static修飾的變量稱為“靜態(tài)變量”或“類變量”。可被對象調(diào)用的非靜態(tài)變量稱為“成員變量”或“實(shí)例變量”。

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

  (1)存放位置:類變量隨著類的加載而存在于“方法區(qū)”中。實(shí)例變量隨著對象的建立而存在“堆內(nèi)存”中。

  (2)生命周期:類變量生命周期最長,隨著類的消失而消失。實(shí)例變量生命周期隨著對象的消失而消失。

  4static使用注意事項(xiàng)

  (1)static方法只能訪問“靜態(tài)成員”。非static方法既可以訪問static成員,也可以訪問非靜態(tài)成員。

  (2)static方法中,不可以定義this,super等關(guān)鍵字。因?yàn)殪o態(tài)優(yōu)先于對象存在。

  (3)main函數(shù)是靜態(tài)的。

  5、static的利弊

  利:對對象共享數(shù)據(jù)進(jìn)行單獨(dú)空間的存儲(chǔ),節(jié)省空間;可以直接被類名調(diào)用。

  弊:生命周期過長。訪問出現(xiàn)局限性。(靜態(tài)雖好,只能訪問靜態(tài))。

  6、main函數(shù)是靜態(tài)的

 ?。?)主函數(shù)是一個(gè)特殊的函數(shù),是程序的入口,可以被JVM調(diào)用。

 ?。?)主函數(shù)定義:public:代表著該函數(shù)訪問權(quán)限是最大的。static:代表主函數(shù)隨著類的加載就已經(jīng)存在了。void:主函數(shù)沒有具體的返回值。main:不是關(guān)鍵字,但是一個(gè)特殊的單詞,可以被JVM識別。String[] arr:函數(shù)的參數(shù),是一個(gè)字符串?dāng)?shù)組。

 ?。?)主函數(shù)是固定格式的:被JVM識別。JVM在調(diào)用主函數(shù)時(shí),傳入的是new String[0]??梢詫ain函數(shù)的參數(shù)args輸出查看。

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

 ?。?)從兩方面下手: 即“靜態(tài)變量”和“靜態(tài)函數(shù)”。

  (2)什么時(shí)候定義靜態(tài)變量(類變量)呢?當(dāng)對象中出現(xiàn)共享數(shù)據(jù)時(shí),該數(shù)據(jù)被靜態(tài)所修飾。對象中的特有數(shù)據(jù)要定義成非靜態(tài),存在于堆內(nèi)存中。

 ?。?)什么時(shí)候定義靜態(tài)函數(shù)呢?當(dāng)功能內(nèi)部沒有訪問到非靜態(tài)數(shù)據(jù)(對象的特有數(shù)據(jù)),那么該功能可以定義成靜態(tài)的。

  8、Java幫助文檔的制作(Javadoc

  在類文件ArrayToolDemo.java文件中,有文檔注釋如下:

  /**

    這是一個(gè)可以對數(shù)組進(jìn)行操作的工具類,提供了……功能。

    @ author xxx

    @ version v1.0

    @ param xxx

    @ return xxx

  */

  在dos命令行中輸入命令:javadoc -d myhelp -author-version ArrayToolDemo.java,則Java中的javadoc工具就會(huì)幫我們完成幫助文檔(也稱API文檔)的制作。

  9、靜態(tài)代碼塊

 ?。?)定義格式:static { 靜態(tài)代碼塊中的語句 }

  (2)特點(diǎn):隨著類的加載而執(zhí)行,只執(zhí)行一次。并優(yōu)先先于main函數(shù)。用于對類進(jìn)行初始化。

  10、對象的初始化過程

  定義一個(gè)對象,都做了什么事情?

 ?。?)把類名.class文件加載到內(nèi)存中。

  (2)執(zhí)行該類中的static代碼塊,如果有得話,給該類進(jìn)行初始化。

  (3)在堆內(nèi)存中開辟空間,分配內(nèi)存地址給對象。

 ?。?)在堆內(nèi)存中建立對象的特有屬性,并進(jìn)行默認(rèn)初始化。

 ?。?)對屬性進(jìn)行顯示初始化。

  (6)對對象進(jìn)行構(gòu)造代碼塊初始化。

  (7)對對象進(jìn)行對應(yīng)構(gòu)造函數(shù)初始化。

  (8)將內(nèi)存地址賦給棧內(nèi)存中的對象名變量。

 ?。﹩卫O(shè)計(jì)模式

  1、設(shè)計(jì)模式:解決某一問題最行之有效的方法。java有23種設(shè)計(jì)模式。

  2、單例設(shè)計(jì)模式:解決一個(gè)類在內(nèi)存中只存在一個(gè)對象的問題。

  3、問題:如何保證對象的唯一呢?

 ?。?)為避免其他程序過多建立該類對象,先禁止其他程序建立該類對象。

  (2)為了讓其他的程序可以訪問到該類對象,只好在本類中自定義一個(gè)對象。

  (3)為方便其他程序?qū)ψ远x對象的訪問,可以對外提供一些訪問方式。

  上述三步如何通過代碼實(shí)現(xiàn)來體現(xiàn)呢?

  (1)將構(gòu)造函數(shù)用private私有化。

 ?。?)在類中創(chuàng)建一個(gè)本類對象。

 ?。?)提供一個(gè)方法可以獲取該類對象。

  注解:對事物該怎么描述,還怎么描述。當(dāng)需要將該事物的對象保證在內(nèi)存中唯一時(shí),就加上以上三步。

  4、餓漢式、懶漢式

 ?。?)單例設(shè)計(jì)模式一:餓漢式

class Single{    private Single(){}    private static Single s = new Single();    public static Single getInstance(){        return s;    }}

  注釋說明:餓漢式的特點(diǎn)是先初始化對象。如:Single類一進(jìn)內(nèi)存,就已經(jīng)創(chuàng)建好了對象。在實(shí)際開發(fā)中,出于安全考慮,建議使用此方式。

 ?。?)單例設(shè)計(jì)模式二:懶漢式(又稱:延時(shí)加載)

 1 class Single 2 { 3      private static Single s=null; 4      private Single(){}  5      public static Single getInstance() 6      { 7           If(s==null) 8                s=new Single(); 9           return s;10      }11 }

  注釋說明:是方法被調(diào)用時(shí),才進(jìn)行初始化。如:以上代碼中,Single類進(jìn)內(nèi)存,對象還沒有存在,只有調(diào)用了getInstance()方法時(shí),才創(chuàng)建對象。在多線程同時(shí)調(diào)用時(shí),懶漢式易出問題。

三、繼承(extends

 ?。ㄒ唬├^承的概述

  繼承是面向?qū)ο蟮囊粋€(gè)重要特征。當(dāng)多個(gè)類中存在相同屬性和行為時(shí),將這些內(nèi)容抽取到單獨(dú)一個(gè)類中,那么多個(gè)類無需再定義這些屬性和行為,只要繼承抽取共同屬性的類即可。這時(shí),多個(gè)類可以稱為子類,單獨(dú)的這個(gè)類被稱為父類或超類。

  當(dāng)類與類之間就存在了繼承的關(guān)系,子類可以直接訪問父類中的非私有的屬性和行為。在代碼中通過extends關(guān)鍵字表示繼承關(guān)系。

  繼承的定義格式:格式:[修飾符] class SubClass extends SuperClass{}

  (二)繼承特點(diǎn)

  1、提高了代碼的復(fù)用性。

  2、讓類之間產(chǎn)生關(guān)系,催生了類的多態(tài)特性。

  3、類與類之間的所屬關(guān)系是is-a

  4、java語言只支持單繼承,不支持多繼承(因?yàn)槎嗬^承帶來安全隱患,當(dāng)多個(gè)父類中定義了相同功能,當(dāng)功能內(nèi)容不同時(shí),子類對象不確定要運(yùn)行哪一個(gè))

  5、Java保留了“多繼承”機(jī)制,用“接口(interface)”完成“多實(shí)現(xiàn)”,實(shí)現(xiàn)接口的關(guān)鍵字implements

  6、Java支持“多層繼承”,也就是一個(gè)繼承體系。

 ?。ㄈ┳痈割愔谐蓡T變量

  繼承關(guān)系出現(xiàn)后,類成員包括:變量,函數(shù),構(gòu)造函數(shù)。

  1、變量

  如果子類中出現(xiàn)非私有的同名成員變量時(shí),子類要訪問本類中的變量,用this。子類要訪問父類中的同名變量,用super。

  super的使用和this的使用幾乎一致,且兩者都存在于方法區(qū)中。this表示本來對象的引用。super表示父類對象的引用。

  2、子父類中函數(shù)的特點(diǎn)——覆蓋(重寫)

  當(dāng)子父類出現(xiàn)同名函數(shù)時(shí),當(dāng)子類對象調(diào)用該函數(shù),會(huì)運(yùn)行子類函數(shù)的內(nèi)容。如同父類的函數(shù)被覆蓋一樣。這種情況是函數(shù)的另一個(gè)特性:重寫(覆蓋)。

  當(dāng)子類繼承父類,沿襲了父類的功能到子類中。但子類雖具備該功能與父類不同,這時(shí),沒有必要定義新功能,而是使用覆蓋特性,保留父類的功能定義,并重寫功能內(nèi)容。子類同時(shí)具有父類方法中的內(nèi)容時(shí),可以用super.方法()。

  注意:(1)子類覆蓋父類,必須保證子類權(quán)限大于父類權(quán)限,才可以覆蓋,否則編譯失敗。(2)靜態(tài)只能覆蓋靜態(tài)。(3)父類中的私有方法不能被覆蓋。

  重載(Overload):只看同名函數(shù)的參數(shù)列表。

  重寫(Override):子父類方法要一模一樣。

  3、構(gòu)造函數(shù)

  在對子類對象進(jìn)行初始化時(shí),父類構(gòu)造函數(shù)也會(huì)運(yùn)行。那是因?yàn)樽宇惖拿恳粋€(gè)構(gòu)造函數(shù)默認(rèn)第一行有一條隱式的語句super()。super():會(huì)訪問父類中空參數(shù)的構(gòu)造函數(shù)。而且子類中所有的構(gòu)造函數(shù)默認(rèn)第一行都是super()。

  問題:為什么子類實(shí)例化一定要訪問父類中的構(gòu)造函數(shù)?

  因?yàn)楦割愔械臄?shù)據(jù)子類可以直接獲取,所以子類在建立對象時(shí),需要先查看父類是如何對這些數(shù)據(jù)進(jìn)行初始化的。所以子類在對象初始化時(shí),要先訪問一下父類中的構(gòu)造函數(shù)。

  如果要訪問父類中指定的構(gòu)造函數(shù),可以通過手動(dòng)定義super語句的方式來指定。在上面的示例中已經(jīng)有了很好的體現(xiàn)。

  注:super語句一定定義在子類構(gòu)造函數(shù)中的第一行。

  構(gòu)造函數(shù)結(jié)論:

  ① 子類的所有構(gòu)造函數(shù),默認(rèn)都會(huì)訪問父類中空參數(shù)的構(gòu)造函數(shù)。因?yàn)樽宇惖拿恳粋€(gè)構(gòu)造函數(shù)內(nèi)的第一行都有一句隱式super()。

 ?、?當(dāng)父類中沒有空參數(shù)的構(gòu)造函數(shù)時(shí),子類必須手動(dòng)通過supe語句形式來指定要訪問父類中的構(gòu)造函數(shù)。

 ?、?當(dāng)然,子類的構(gòu)造函數(shù)第一行也可以手動(dòng)指定this語句形式來訪問本類中的構(gòu)造函數(shù)。子類中至少會(huì)有一個(gè)構(gòu)造函數(shù)會(huì)訪問父類中的構(gòu)造函數(shù)。

  知識點(diǎn):為什么this()和super()不能在同一個(gè)構(gòu)造函數(shù)中?因?yàn)樗鼈兌嘉挥趬蛟酆瘮?shù)的第一行,且兩不能在同一行。為什么不能再同一行?因?yàn)槌跏蓟瘎?dòng)作要先做,而在子類構(gòu)造函數(shù)中必有一個(gè)this語句或者super語句。

 ?。ㄋ模?/strong>final關(guān)鍵字

  final作為一個(gè)修飾符。具有以下特點(diǎn):

  1、可以修飾類、函數(shù)、變量。

  2、被final修飾的類不可以被繼承,這樣就可以避免被繼承、被子類復(fù)寫功能,打破“封裝性”。

  3、被final修飾的方法不可以被覆寫。

  4、被final修飾的變量是一個(gè)常量,只能賦值一次,既可以修飾“成員變量”,又可以修飾“局部變量”。(作為常量:所有的字母都大寫;多個(gè)單詞,用下劃線連接)。

  5、內(nèi)部類定義在類中的局部位置上時(shí),只能訪問該局部被final修飾的局部變量。

四、抽象類(abstract class

 ?。ㄒ唬┒x

  1、Java中可以定義沒有方法體的方法,該方法的具體實(shí)現(xiàn)由子類完成,該方法稱為抽象方法,包含抽象方法的類就是抽象類。

  2、抽象類的由來

  多個(gè)對象都具備相同的功能,但是功能具體內(nèi)容有所不同,那么在抽取過程中,只抽取了功能定義,并未抽取功能主體,那么只有功能聲明,沒有功能主體的方法稱為抽象方法。

  (二)抽象的特點(diǎn)

  1、抽象方法一定定義在抽象類中。

  2、抽象類和抽象方法必須用abstract關(guān)鍵字來修飾。

  3、 抽象類不可以被實(shí)例化,即不可以用new創(chuàng)建對象。

  4、抽象類中的抽象方法被使用,必須有子類覆寫后,建立子類對象進(jìn)行調(diào)用。如果子類只覆蓋了部分抽象方法,那么子類還是一個(gè)抽象類。

  5、抽象方法只有方法聲明,沒有方法體,定義在抽象類中。

  注:抽象類中可以有非抽象的方法。

  6、抽象類及抽象方法的定義格式,示例代碼如下:

1 abstract class Demo{2     abstract void show();    //抽象方法3     abstract void inof();        //抽象方法4     void turn(){}    //一般方法5 }

  (三)抽象類的一些細(xì)節(jié)問題

  1、抽象類中有構(gòu)造函數(shù)嗎?

  答:有,用于給子類對象進(jìn)行初始化。

  2、抽象類可以不定義抽象方法嗎?

  答:可以,但很少見,目的是不讓該類創(chuàng)建對象。AWT的適配器對象就是這種類。

  3、抽象關(guān)鍵字不可以和那些關(guān)鍵字共存?

  答:private(因?yàn)榉椒ㄒ桓采w)、static(不用創(chuàng)建對象)、final(覆蓋還是不覆蓋?)

  4、抽象類和一般類的異同點(diǎn):

  相同點(diǎn):抽象類和一般類都是用來描述事物的,都在內(nèi)部定義成員。

  不同點(diǎn):(1)一般類有足夠的信息描述事物。抽象了描述事物的信息有可能不足。(2)一般類中不能定義抽象方法,只能定義非抽象方法。抽象類中既可以定義抽象方法,又可以定義非抽象方法。(3)一般類可以被實(shí)例化。抽象方法不可以被實(shí)例化。

  5、抽象類一定是個(gè)父類嗎?是的。

  (四)抽象類應(yīng)用示例代碼

    /* 需求:假如我們在開發(fā)一個(gè)系統(tǒng)時(shí)需要對員工進(jìn)行建模,員工包含 3 個(gè)屬性:姓名、工號以及工資。經(jīng)理也是員工,除了含有員工的屬性外,另為還有一個(gè)獎(jiǎng)金屬性。請使用繼承的思想設(shè)計(jì)出員工類和經(jīng)理類。要求類中提供必要的方法進(jìn)行屬性訪問。

    分析:員工類:name id pay。經(jīng)理類:繼承了員工,并有自己特有的bonus。*/

 1 //員工類,也是父類  2 abstract class Employee{ 3       private String name;//姓名 4      private String id;  //工號 5      private double pay;  //工資 6  7      //自定義構(gòu)造函數(shù)初始化  8      Employee(String name,String id,double pay){  9             this.name = name;10             this.id = id; 11             this.pay = pay;12       }13       public abstract void work();//抽象的工作方法14 }15 16 //經(jīng)理類,繼承員工類17 class Manager extends Employee{18       private int bonus;//特有的獎(jiǎng)金屬性19       Manager(String name,String id,double pay,int bonus) {//子類的構(gòu)造方法20       super(name,id,pay);//調(diào)用超類中的構(gòu)造器21       this.bonus = bonus;22       }23       public void work(){//經(jīng)理類的工作方法內(nèi)容24       System.out.println("manager work");25       }26 }27 28 //普通員工類,繼承員工類29 class Pro extends Employee{30       Pro(String name,String id,double pay){31       super(name,id,pay);32       }33       public void work(){        //普通員工類的工作方法內(nèi)容34       System.out.println("pro work");35       }36 }37 38 class  AbstractDemo{39       public static void main(String[] args){40       new Manager("manager","001",10000,2000).work();41       new Pro("pro","020",5000).work(); 42       }43 }

五、接口interface

 ?。ㄒ唬┙涌诘母攀?/strong>

  1、接口定義

  接口可以被認(rèn)為是一個(gè)特殊的抽象類。當(dāng)抽象類中的方法都是抽象的,那么該類可以通過接口的形式來表示。接口使用interface來表示,子類中用implements實(shí)現(xiàn)。格式為:

  interface 接口名{}

  子類名 implements接口名{}

  2、格式特點(diǎn)

  (1)接口中常見定義:常量,抽象方法。

 ?。?)接口中的成員都有固定修飾符。常量:public static final。方法:public abstract

 ?。?)接口中的成員都是public的。

  在使用中,常量可以不寫publicstatic final,方法可以不寫public abstract,編譯時(shí)Java會(huì)自動(dòng)添加這些修飾符,因?yàn)檫@是固定的格式修飾符。但為了方便閱讀,通常我們都寫上。

 ?。ǘ┙涌诘奶攸c(diǎn)

  1、接口是對外暴露的規(guī)則。

  2、接口是程序的功能擴(kuò)展。

  3、接口的出現(xiàn)降低耦合性。

  4、接口可以由類多實(shí)現(xiàn)。這也是對多繼承不支持的轉(zhuǎn)換形式。java支持多實(shí)現(xiàn)。

  5、類與接口之間是“實(shí)現(xiàn)關(guān)系”,而且類可以繼承一個(gè)類的同時(shí)實(shí)現(xiàn)多個(gè)接口。

  6、接口之間可以有繼承關(guān)系,而且可以多繼承,因?yàn)榻涌跊]有方法體。

  注:(1)接口不可以創(chuàng)建對象的,因?yàn)橛谐橄蠓椒?。需要被子類?shí)現(xiàn)(implements),子類對接口中的抽象方法全都覆蓋后,子類才可以進(jìn)行實(shí)例化。否則子類是一個(gè)抽象類。(2)實(shí)現(xiàn)多個(gè)接口時(shí),接口中不可以有返回不同類型的同名抽象函數(shù)。這樣子類實(shí)現(xiàn)時(shí)將不能復(fù)寫。

 ?。ㄈ┙涌谂c抽象類的

  相同點(diǎn):都是不斷向上抽取而來。

  不同點(diǎn):(1)抽象類需要被繼承,只能是單繼承。接口需要被實(shí)現(xiàn),可以使多實(shí)現(xiàn)。(2)抽象類中可以定義抽象方法和非抽象方法,子類繼承后可以直接使用非抽象方法。接口只能是定義抽象方法,必須由子類去實(shí)現(xiàn)。(3)繼承關(guān)系是is-a。實(shí)現(xiàn)關(guān)系是like。繼承體系是共性內(nèi)容;實(shí)現(xiàn)關(guān)系是額外功能。(4)抽象類中可以私有變量或方法。接口中的常量和方法都是public修飾的權(quán)限。

 ?。ㄋ模┙涌诘膽?yīng)用示例

  /*需求:筆記本電腦使用。為了擴(kuò)展筆記本的功能,但日后出現(xiàn)什么功能設(shè)備不知道。

  分析:定義一個(gè)規(guī)則,只要日后出現(xiàn)的設(shè)備都符合這個(gè)規(guī)則就可以了。規(guī)則在java中就是接口。*/

 1 interface USB// 暴露的規(guī)則。 2 { 3     public void open(); 4     public void close(); 5 } 6 class BookPC 7 { 8     public static void main(String[] args) 9     {10         useUSB(new UPan());//功能擴(kuò)展了。11         useUSB(new UsbMouse());12     }13     //使用規(guī)則。14     public static void useUSB(USB u)//接口類型的引用,用于接收(指向)接口的子類對象。//USB u= new UPan();15     {16         if(u!=null)17         {18             u.open();19             u.close();20         }21     }22 }23 //一年后。------------------------------24 //實(shí)現(xiàn)規(guī)則。25 //這些設(shè)備和電腦的耦合性降低了。26 class UPan implements USB27 {28     public void open()29     {30         System.out.println("upan open");31     }32     public void close()33     {34         System.out.println("upan close");35     }36 }37 class UsbMouse implements USB38 {39     public void open()40     {41         System.out.println("UsbMouse open");42     }43     public void close()44     {45         System.out.println("UsbMouse close");46     }47 }

六、多態(tài)

  (一)多態(tài)的概述

  1、對多態(tài)的理解:指同一個(gè)實(shí)體同時(shí)具有多種形式,也可以理解為事物存在的多種體現(xiàn)形態(tài)。例如動(dòng)物中貓和狗。貓這個(gè)對象對應(yīng)的類型是貓類型,如:貓 cat1 = new 貓()。同時(shí)貓也是動(dòng)物的一種,因此也可以把貓稱為動(dòng)物。動(dòng)物 cat1 = new貓()。那么動(dòng)物就是從貓和狗等具體事物中抽取出來的父類型。

  2、多態(tài)在代碼中的體現(xiàn):父類或接口的引用指向其子類對象。如Animal a = new Dog()。

  3、多態(tài)的好處:提高代碼的擴(kuò)展性,前期定義的代碼可以使用后期的內(nèi)容。

  4、多態(tài)的弊端

 ?。?)前期定義的內(nèi)容,不能使用后期特有內(nèi)容。

 ?。?)只能使用父類中的引用訪問父類中的成員。也就是說使用了多態(tài),父類型的引用在使用功能時(shí),不能直接調(diào)用子類中的特有方法。如Animal a = new Cat(); 這代碼就是多態(tài)的體現(xiàn),假設(shè)子類Cat中有特有的抓老鼠功能,父類型的 a就不能直接調(diào)用。這上面的代碼中,可以理解為Cat類型提升了,向上轉(zhuǎn)型。如果此時(shí)父類的引用想要調(diào)用Cat中特有的方法,就需要強(qiáng)制將父類的引用轉(zhuǎn)成子類類型,向下轉(zhuǎn)型。如:Catc = (Cat)a;

注:如果父類可以創(chuàng)建對象,如Animal a = new Animal()。此時(shí)就不能向下轉(zhuǎn)型,Cat c = (Cat)a這樣的代碼就變得不容許,編譯時(shí)會(huì)報(bào)錯(cuò)。所以千萬不能出現(xiàn)這樣的操作,就是將父類對象轉(zhuǎn)成子類類型。我們所說的能夠轉(zhuǎn)換指的是父類引用指向自己的子類對象時(shí),該引用可以被提升,也可以被強(qiáng)制轉(zhuǎn)換。多態(tài)始終都是子類對象在做著變化。

  5、多態(tài)的前提

 ?。?)類與類之間必須有關(guān)系,要么繼承,要么實(shí)現(xiàn)。

 ?。?)存在覆蓋。父類中有方法被子類重寫。

  6、多態(tài)的類型判斷

  instanceof用于判斷對象的具體類型。

  (二)多態(tài)中成員的特點(diǎn)

  1、多態(tài)中成員變量的特點(diǎn)

  無論編譯和運(yùn)行,都參考左邊(引用變量所屬的類)。如:多態(tài)中的父類引用調(diào)用成員變量時(shí),如果父類和子類有同名的成員變量,那么被調(diào)用的是父類中的成員變量。

  2、多態(tài)中非靜態(tài)成員函數(shù)的特點(diǎn)

  在編譯時(shí)期:參考引用型變量所屬的類中是否有調(diào)用成員函數(shù)。如果有,編譯通過,如果沒有編譯失敗。

  在運(yùn)行時(shí)期:參閱對象所屬的類中是否有調(diào)用的方法。這就是說,如果父類中有一個(gè)非抽象的方法,而子類繼承后又將其覆寫,在多態(tài)運(yùn)行時(shí),父類的引用調(diào)用這個(gè)同名函數(shù)時(shí),被運(yùn)行的將是父類中的方法。

  簡單總結(jié)就是:成員函數(shù)在多態(tài)調(diào)用時(shí),編譯時(shí)看左邊,運(yùn)行時(shí)看右邊。

  3、多態(tài)中靜態(tài)成員函數(shù)的特點(diǎn)

  無論編譯和運(yùn)行,都參考左邊。也就是父類引用在調(diào)用靜態(tài)同名函數(shù)時(shí),被調(diào)用的是父類中的靜態(tài)函數(shù)。這是因?yàn)椋?dāng)類一被加載,靜態(tài)函數(shù)就隨類綁定在了內(nèi)存中。此時(shí),不需要?jiǎng)?chuàng)建對象,就可以使用類名直接調(diào)用。

  注:類在方法區(qū)中的分配,分為靜態(tài)區(qū)和非靜態(tài)區(qū),而關(guān)鍵字this和super在非靜態(tài)區(qū)。

  (三)多態(tài)應(yīng)用的代碼示例

  /*電腦的運(yùn)行實(shí)例。電腦的運(yùn)行由主板控制,假設(shè)主板只是提供電腦運(yùn)行,但是沒有上網(wǎng),聽歌等功能。而上網(wǎng)、聽歌需要硬件的支持。而現(xiàn)在主板上沒有網(wǎng)卡和聲卡,這時(shí)可以定義一個(gè)規(guī)則,叫PCI,只要符合這個(gè)規(guī)則的網(wǎng)卡和聲卡都可以在主板上使用,這樣就降低了主板和網(wǎng)卡、聲卡之間的耦合性。用程序體現(xiàn)。*/

 1 // 接口PCI 2 interface PCI{ 3       void open(); 4       void close(); 5 } 6  7 //網(wǎng)卡實(shí)現(xiàn)接口 8 class NetCard implements PCI{ 9       public void open(){10             System.out.println("NetCard_open");11       }12       public void close(){13             System.out.println("NetCard_close");14       }15 }16 17 //聲卡實(shí)現(xiàn)接口18 class SoundCard implements PCI{19       public void open(){20             System.out.println("SoundCard_open");21       }22       public void close(){23             System.out.println("SoundCard_close");24       }25 }26 27 class Mainboard{28       //電腦運(yùn)行29       public static void run(){30             System.out.println("Mainboard_run");31       }32       //使用擴(kuò)展功能33       public static void usePCI(PCI p) {//接口型引用指向自己的子類對象。//PCI p = new NetCard()34             if(!(p==null)){35                   p.open();36                   p.close();37             }38       }39 }40 41 class Demo{42       public static void main(String[] args) {43             Mainboard m =new Mainboard();44             //電腦運(yùn)行45             m.run();46             //m.usePCI(null);47             //電腦上網(wǎng)48             m.usePCI(new NetCard());49             //電腦聽歌50             m.usePCI(new SoundCard());51       }52 }

七、內(nèi)部類

 ?。ㄒ唬└攀?/strong>

  將一個(gè)類定義在另一個(gè)類的里面,對里面那個(gè)類就稱為內(nèi)部類(內(nèi)置類,嵌套類)。編譯時(shí),如果代碼中有內(nèi)部類,生成的class文件中會(huì)含有這樣的文件:Test$1.class。編譯器將會(huì)把內(nèi)部類翻譯成用$(美元符號)分隔外部類名和內(nèi)部類名的常規(guī)類文件。

 ?。ǘ﹥?nèi)部類的訪問規(guī)則

  1、內(nèi)部類可以直接訪問外部類中的成員,包括私有。之所以可以直接訪問外部類中的成員,是因?yàn)閮?nèi)部類中持有了一個(gè)外部類的引用,格式:外部類名.this。

  2、外部類要訪問內(nèi)部類,必須建立內(nèi)部類對象。

 ?。ㄈ┰L問格式

  1、當(dāng)內(nèi)部類定義在外部類的成員位置上,而且非私有,可以在外部類的方法中,創(chuàng)建內(nèi)部類的對象,然后調(diào)用。格式:Outer.Inner in = new Outer().new Inner();

  2、當(dāng)內(nèi)部類在外部類中的成員位置上時(shí),可以被成員修飾符private所修飾,private將內(nèi)部類在外部類中進(jìn)行封裝。 訪問格式:Outer.this.x。

  3、static靜態(tài)內(nèi)部類:static內(nèi)部類具備static特性。當(dāng)內(nèi)部類被static修飾后,只能直接訪問外部類中的static成員,出現(xiàn)訪問局限。

  4、在外部類中,直接訪問static內(nèi)部類的非靜態(tài)函數(shù)。格式:new Outer.Inner().function。

  5、在外部其他類中,直接訪問static內(nèi)部類的靜態(tài)成員。格式為:Outer.Inner.function();

  注意:(1)當(dāng)內(nèi)部類中定義了靜態(tài)成員時(shí),則內(nèi)部類必須是static的。(2)當(dāng)外部類中的靜態(tài)方法訪問內(nèi)部類時(shí),內(nèi)部類也必須是static的。(3)在實(shí)際應(yīng)用中,內(nèi)部類通常被定義為private,而很少定義為public。

  6、內(nèi)部類定義的原則

  當(dāng)描述事物時(shí),事物的內(nèi)部還有事物,該事物用內(nèi)部類來描述。因?yàn)閮?nèi)部事物在使用外部事物的內(nèi)容。

  (三)局部內(nèi)部類(內(nèi)部類定義在局部時(shí))

  內(nèi)部類定義在外部類中的某個(gè)方法中,創(chuàng)建了這個(gè)類型的對象時(shí),且僅使用了一次,那么可在這個(gè)方法中定義局部內(nèi)部類。

  1、不可以被成員修飾符(如public、private、static等)修飾。其作用域被限定在了聲明這個(gè)局部類的代碼塊中

  2、可以直接訪問外部類中的成員,因?yàn)檫€持有外部類中的引用。內(nèi)部類在局部位置上,不可以訪問它所在的局部中的變量,只能訪問被final修飾的局部變量。

  (四)匿名內(nèi)部類

  1、匿名內(nèi)部類其實(shí)就是內(nèi)部類的簡寫格式。

  2、定義匿名內(nèi)部類的前提:內(nèi)部類必須是繼承一個(gè)類或者實(shí)現(xiàn)接口。

  3、匿名內(nèi)部類的格式: new父類或者接口(){定義子類的內(nèi)容}

  4、其實(shí)匿名內(nèi)部類就是一個(gè)匿名子類對象??梢岳斫鉃閹?nèi)容的對象。

  5、匿名內(nèi)部類中定義的方法最好不要超過3個(gè)。

 ?。ㄎ澹┠涿麅?nèi)部類的應(yīng)用示例

 1 interface Inter{ 2       void method(); 3 } 4  5 class InnerClassTest{ 6       public static void main(String[] args){ 7             show( new Inter(){ 8                   public void method(){ 9                         System.out.println("method show run");10                   }11             });12       }13       public static void show(Inter in){14             in.method();15       }16 }

---------- android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 新竹县| 余庆县| 平塘县| 武城县| 泰安市| 桃江县| 邵阳县| 云和县| 宝丰县| 邢台市| 石台县| 莫力| 镇康县| 琼中| 新宾| 遂川县| 许昌市| 建昌县| 邢台县| 沅江市| 佛教| 蓬溪县| 顺昌县| 兴海县| 商水县| 红原县| 海淀区| 修武县| 西昌市| 桃源县| 尚志市| 阳山县| 双辽市| 贞丰县| 孝义市| 龙胜| 西峡县| 汉中市| 莱西市| 甘洛县| 田林县|