Java EE 第二篇 面向?qū)ο?/h1>


面向?qū)ο蠡A(chǔ)

一求厕、面向?qū)ο蟮母拍睿?/h4>

站在更高的層次美浦,省略我們自己對(duì)細(xì)節(jié)的關(guān)注,讓對(duì)象替我們完成具體的工作荤牍。我們只需要“使喚”對(duì)象即可康吵。面對(duì)更復(fù)雜的場(chǎng)景,我們可以輕易組織對(duì)象應(yīng)對(duì)更靈活惭载、更多的變化,同時(shí)可以提高代碼的復(fù)用性含长。舉例好比我們招來“管家”拘泞、“秘書”、“保姆”诗鸭,我們指揮管家,管家指揮保姆请唱,保姆完成最后做飯的工作十绑,對(duì)應(yīng)實(shí)際項(xiàng)目中本橙,則是通過對(duì)象指揮其他對(duì)象,最終完成工作亏狰,我們更多則關(guān)注如何設(shè)計(jì)對(duì)象,以及組織對(duì)象之間的工作策州,涉及架構(gòu)問題。

二孽糖、類與對(duì)象:

要讓對(duì)象能夠替我們完成工作,就要設(shè)計(jì)出類誉尖,按照類來創(chuàng)建對(duì)象,類就好比圖紙探熔,對(duì)象則是按照?qǐng)D紙生產(chǎn)出來的產(chǎn)品柬甥,包含數(shù)據(jù)和方法其垄。類必須通過對(duì)象來使用苛蒲,不能拿著“圖紙”就去干活兒。但是我們也不能直接使用對(duì)象绿满,最終能操縱的是一個(gè)對(duì)象的引用(reference)臂外。在這里有一個(gè)很形象的比喻:你可以把車鑰匙和車看作是一組對(duì)象引用和對(duì)象的組合。當(dāng)你想要開車的時(shí)候喇颁,你首先需要拿出車鑰匙點(diǎn)擊開鎖的選項(xiàng)漏健,停車時(shí)橘霎,你需要點(diǎn)擊加鎖來鎖車谭溉。車鑰匙相當(dāng)于就是引用,車就是對(duì)象,由車鑰匙來驅(qū)動(dòng)車的加鎖和開鎖城丧。并且愿卸,即使沒有車的存在,車鑰匙也是一個(gè)獨(dú)立存在的實(shí)體园骆,也就是說滋捶,你有一個(gè)對(duì)象引用垮衷,但你不一定需要一個(gè)對(duì)象與之關(guān)聯(lián)仰迁,也就是說可以創(chuàng)建一個(gè)空的引用,在需要時(shí)與對(duì)象進(jìn)行關(guān)聯(lián)再使用。

類必須存在.java文件中县恕,一個(gè)文件可以存在N個(gè)類师坎,但是只能存在一個(gè)public修飾的類作為主類犯眠,類名與文件名保持一致。

類由屬性和方法組成:

  • 屬性:就相當(dāng)于人的一個(gè)個(gè)的特征
  • 方法:就相當(dāng)于人的一個(gè)個(gè)的行為泉瞻,例如:說話、吃飯芹啥、唱歌梆暮、睡覺
類定義格式:
class 類名稱{
    成員屬性
    成員方法
}
屬性與方法:
屬性定義格式:
    數(shù)據(jù)類型 屬性名;
屬性定義并賦值的格式:
    數(shù)據(jù)類型 屬性名 = 初始化值;
    
方法定義格式:
    權(quán)限修飾符 返回值類型 方法名(形式參數(shù)列表){
        //方法體
        return 返回值铣揉;
    }
通過對(duì)象使用:
類名稱 對(duì)象名稱 = new 類名稱() ; //創(chuàng)建引用并與對(duì)象進(jìn)行關(guān)聯(lián)
訪問類中的屬性: 對(duì)象.屬性 ;
調(diào)用類中的方法: 對(duì)象.方法(實(shí)際參數(shù)列表) ;

三、創(chuàng)建對(duì)象內(nèi)存分析:

1讲婚、棧

棧內(nèi)存通過 '棧指針' 來創(chuàng)建空間與釋放空間,指針向下移動(dòng), 會(huì)創(chuàng)建新的內(nèi)存, 向上移動(dòng), 會(huì)釋放這些內(nèi)存错维,這種移動(dòng)的方式, 必須要明確移動(dòng)的大小與范圍械筛,這是一個(gè)對(duì)于數(shù)據(jù)存儲(chǔ)的限制, 存儲(chǔ)的數(shù)據(jù)大小是固定的 , 影響了程序 的靈活性晨逝,也就是說通過類設(shè)計(jì)的對(duì)象永遠(yuǎn)不會(huì)存儲(chǔ)在棧內(nèi)存中。

只能存儲(chǔ)基本數(shù)據(jù)類型冬念,引用數(shù)據(jù)類型的引用趁窃。

棧內(nèi)存存取速度非常快刘急,僅次于寄存器棚菊。Java中棧區(qū)的大小約為2M浸踩。

2叔汁、堆

存放對(duì)象,通過new關(guān)鍵字創(chuàng)建的變量检碗,通過new關(guān)鍵字通知虛擬機(jī)在堆內(nèi)存中開辟一塊空間据块,其中內(nèi)存的釋放由GC負(fù)責(zé)。GC回收的原則是折剃,棧內(nèi)存中不存在此對(duì)象的引用時(shí)另假,則視其為垃圾,進(jìn)行回收怕犁。堆內(nèi)存與棧內(nèi)存不同, 優(yōu)點(diǎn)在于我們創(chuàng)建對(duì)象時(shí) , 不必關(guān)注堆內(nèi)存中需要開辟多少存儲(chǔ)空間 , 也不需要關(guān)注內(nèi)存占用時(shí)長(zhǎng)边篮。

3、方法區(qū)

存放類奏甫、靜態(tài)變量戈轿、常量、成員方法阵子,常量池中包含static修飾的成員思杯,字符串常量池后來移動(dòng)到堆內(nèi)存中。

4挠进、PC寄存器

PC寄存器保存的是 當(dāng)前正在執(zhí)行的 JVM指令的 地址色乾。在Java程序中, 每個(gè)線程啟動(dòng)時(shí), 都會(huì)創(chuàng)建一個(gè)PC寄存器誊册。

5、本地方法棧

保存本地(native)方法的地址暖璧。一個(gè)Native Method就是一個(gè)Java調(diào)用非java代碼的接口案怯。一個(gè)Native Method是這樣一個(gè)java的方法:該方法的實(shí)現(xiàn)由非java語言實(shí)現(xiàn),比如C漆撞。這個(gè)特征并非java所特有殴泰,很多其它的編程語言都有這一機(jī)制,比如在C++中浮驳,你可以用extern "C"告知C++編譯器去調(diào)用一個(gè)C的函數(shù)悍汛。

四、構(gòu)造方法

作用: 用于對(duì)象初始化至会。

執(zhí)行時(shí)機(jī): 在創(chuàng)建對(duì)象時(shí),自動(dòng)調(diào)用

特點(diǎn): 所有的Java類中都會(huì)至少存在一個(gè)構(gòu)造方法 如果一個(gè)類中沒有明確的編寫構(gòu)造方法, 則編譯器會(huì)自動(dòng)生成一個(gè)無參的構(gòu)造方法, 構(gòu)造方法中沒有任何的代 碼离咐! 如果自行編寫了任意一個(gè)構(gòu)造器, 則編譯器不會(huì)再自動(dòng)生成無參的構(gòu)造方法。

推薦提供一個(gè)無參數(shù)構(gòu)造函數(shù)與全參數(shù)構(gòu)造方法奉件,將初始化內(nèi)容放置其中宵蛀,在創(chuàng)建對(duì)象時(shí)自動(dòng)調(diào)用。建議自定義無參構(gòu)造方法县貌,不要對(duì)編譯器形成依賴术陶,避免錯(cuò)誤發(fā)生。 當(dāng)類中有非常量成員變量時(shí)煤痕,建議提供兩個(gè)版本的構(gòu)造方法梧宫,一個(gè)是無參構(gòu)造方法,一個(gè)是全屬性做參數(shù)的構(gòu)造方法摆碉。 當(dāng)類中所有成員變量都是常量或者沒有成員變量時(shí)塘匣,建議不提供任何版本的構(gòu)造。

構(gòu)造器初始化:

對(duì)成員屬性可以進(jìn)行默認(rèn)字段的初始化巷帝,如基本類型的初始化忌卤,與引用數(shù)據(jù)類型的初始化默認(rèn)值,也可以指定數(shù)值初始化楞泼。

初始化順序:

靜態(tài)屬性初始化驰徊,靜態(tài)方法塊初始化,普通屬性初始化堕阔,普通方法塊初始化棍厂,構(gòu)造函數(shù)初始化。

public class LifeCycle {
     private static String staticField = getStaticField();

     static {
        System.out.println(staticField);
        System.out.println("靜態(tài)方法初始快");
     }

     private String field = getField();
     {
        System.out.println(field);
     }

     public LifeCycle() {
        System.out.println("構(gòu)造函數(shù)初始化");
     }
     public static String getStaticField() {
         String statiFiled = "Static Field Initial";
         return statiFiled;
     }
     public static String getField() {
         String filed = "Field Initial";
         return filed;
     }

     public static void main(String[] argc) {
        new LifeCycle();
     }
}

五印蔬、方法的重載

兩個(gè)方法的名稱相同勋桶,參數(shù)列表的類型或數(shù)目或順序不同(方法簽名不同),即可完成重載,實(shí)際工作時(shí)例驹,編譯器會(huì)自己選擇最合適的那個(gè)方法捐韩。注意,返回值不是方法簽名的一部分鹃锈,僅返回值類型不同荤胁,不能算作重載,參數(shù)列表的長(zhǎng)度或類型不同即可完成方法的重載屎债。注意區(qū)分重載與重寫仅政,重寫是子類對(duì)父類的方法進(jìn)行子類的實(shí)現(xiàn),而重載是在同一個(gè)類中的盆驹,重寫過程中方法的簽名是完全一致不可以改變的圆丹,只有實(shí)現(xiàn)的邏輯是不一樣的。編譯器會(huì)在重寫處標(biāo)注(Override)躯喇,重載則是Overload辫封。

重載的條件:
  • 方法名稱必須相同。
  • 參數(shù)列表必須不同(個(gè)數(shù)不同廉丽、或類型不同倦微、參數(shù)類型排列順序不同等)。方法的返回類型可以相同也可以不相同正压。
  • 僅僅返回類型不同不足以成為方法的重載欣福。
  • 重載是發(fā)生在編譯時(shí)的,因?yàn)榫幾g器可以根據(jù)參數(shù)的類型來選擇使用哪個(gè)方法焦履。
重寫的原則:
  • 重寫的方法必須要和父類保持一致拓劝,包括返回值類型,方法名,參數(shù)列表也都一樣〔昧迹·重寫的方法可以使用@0verride注解來標(biāo)識(shí)
  • 子類中重寫方法的訪問權(quán)限不能低于父類中方法的訪問權(quán)限凿将。

六校套、匿名對(duì)象

如果本對(duì)象只使用一次价脾,可以使用匿名對(duì)象。反之笛匙,如果對(duì)象的使用至少2次侨把,則必須有引用指向這個(gè)對(duì)象,否則創(chuàng)建之后就找不到了妹孙。匿名對(duì)象只能使用一次秋柄,因?yàn)闆]有任何的對(duì)象引用,所以將稱為垃圾蠢正,等待被G·C回收骇笔。 只使用一次的對(duì)象可以通過匿名對(duì)象的方式完成,這一點(diǎn)在以后的開發(fā)中將經(jīng)常使用到。

七笨触、面向?qū)ο蟮娜筇卣?/h4>

封裝懦傍、繼承、多態(tài)芦劣。


面向?qū)ο筮M(jìn)階

一粗俱、封裝

隱藏類中的數(shù)據(jù)域,對(duì)類中的數(shù)據(jù)屬性進(jìn)行封裝虚吟,提供訪問器與更改器進(jìn)行數(shù)據(jù)的操作寸认。建議在類的設(shè)計(jì)中,對(duì)所有屬性進(jìn)行封裝串慰,并為其提供setter及getter方法進(jìn)行設(shè)置和取得操作偏塞。

class Person{
    private String name ; // 表示姓名
    private int age ; // 表示年齡
    void tell(){
        System.out.println("姓名:" + getName() + ";年齡:" + getAge()) ;
    }
    public void setName(String str){
        name = str ;
    }
    public void setAge(int a){
        if(a>0&&a<150)
            age = a ;
    }
    public String getName(){
        return name ;
    }
    public int getAge(){
        return age ;
    }
};

二邦鲫、this與super關(guān)鍵字

this指向當(dāng)前創(chuàng)建的對(duì)象烛愧,可以使用this完成屬性的訪問,調(diào)用方法掂碱,避免由于方法參數(shù)與類中屬性重名而導(dǎo)致方法的工作異常怜姿。如果你把 this 理解為指向自身的一個(gè)引用,那么super就是指向父類的一個(gè)引用疼燥。super關(guān)鍵字和 this一樣沧卢,你可以使用super.對(duì)象來引用父類的成員,super(參數(shù))調(diào)用父類的構(gòu)造函數(shù)醉者。

三但狭、static靜態(tài)

可修飾:代碼塊、成員變量撬即、成員方法立磁。

被static修飾的成員變量與成員方法稱為類屬性與類方法,在類加載時(shí)即可使用剥槐,不需要?jiǎng)?chuàng)建對(duì)象完成調(diào)用唱歧,使用類名即可調(diào)用。在內(nèi)存中粒竖,均存儲(chǔ)在方法區(qū)颅崩,為所有對(duì)象所共有,只存儲(chǔ)一份蕊苗,不會(huì)隨多個(gè)對(duì)象的創(chuàng)建而產(chǎn)生多個(gè)內(nèi)存中的副本沿后。

靜態(tài)可以不可訪問非靜態(tài),而非靜態(tài)能訪問靜態(tài)朽砰,原因是對(duì)象不一定已經(jīng)創(chuàng)建尖滚,使用靜態(tài)可能是類加載時(shí)期喉刘,沒有創(chuàng)建具體對(duì)象是不能訪問非靜態(tài)的。

四漆弄、代碼塊

1饱搏、構(gòu)造代碼塊

在類中的成員代碼塊, 我們稱其為構(gòu)造代碼塊置逻, 在每次對(duì)象創(chuàng)建時(shí)執(zhí)行推沸, 執(zhí)行在構(gòu)造方法之前∪耄可以隨對(duì)象的創(chuàng)建反復(fù)執(zhí)行多次鬓催。

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

在類中使用static修飾的成員代碼塊恨锚, 我們稱其為靜態(tài)代碼塊宇驾, 在類加載時(shí)執(zhí)行。 每次程序啟動(dòng)到關(guān)閉 猴伶,只會(huì)執(zhí)行一次的代碼塊炬称。

構(gòu)造順序:靜態(tài)代碼塊 --> 構(gòu)造代碼塊 --> 構(gòu)造方法

五涩搓、權(quán)限修飾符:

繼承:

繼承是所有0OP(Object Oriented Programming)語言和Java語言都不可或缺的一部分掰邢。只要我們創(chuàng)建了一個(gè)類界弧,就隱式的繼承自0bject父類,只不過沒有指定办桨。如果你顯示指定了父類筹淫,那么你繼承于父類,而你的父類繼承于Object類呢撞。繼承雙方具有屬性上的共性损姜,并可能發(fā)生方法的重寫。

組合:

組合其實(shí)不難理解殊霞,就是將對(duì)象引用置于新類中即可摧阅。組合也是一種提高類的復(fù)用性的一種方式。如果你想讓類具有更多的擴(kuò)展功能绷蹲,你需要記住一句話多用組合棒卷,少用繼承。

public class SoccerPlayer {
     private String name;
     private Soccer soccer;
}
public class Soccer {
    private String soccerName;
}
繼承與組合的區(qū)別:
代理:

除了繼承和組合外瘸右,另外一種值得探討的關(guān)系模型稱為代理娇跟。代理的大致描述是岩齿,A想要調(diào)用B類的方法太颤,A不直接調(diào)用,A會(huì)在自己的類中創(chuàng)建一個(gè)B對(duì)象的代理盹沈,再由代理調(diào)用B的方法龄章。

六吃谣、單例模式

單例設(shè)計(jì)模式:保證程序在內(nèi)存中只有一個(gè)對(duì)象存在(被程序所共享)

1、懶漢式
//隨著類的加載在內(nèi)存中對(duì)象為null做裙,當(dāng)調(diào)用 getInstance 方法時(shí)才創(chuàng)建對(duì)象(延遲加載)
class Single{
    private Single(){}
    private static Single s1 = null;
    public static Single getInstance(){
        if(s1 == null){
            s1 = new Single();
        }
        return s1;
    }
}
2岗憋、餓漢式
//隨著類的加載直接創(chuàng)建對(duì)象(推薦開發(fā)中使用)
class Single2{
    private Single2(){}
    private static Single2 s = new Single2();
    public static Single getInstance(){
        return s;
    }
    void print(){
        System.out.println("Hello World!");
    }
}

實(shí)現(xiàn)步驟:

  1. 保證一個(gè)類只有一個(gè)實(shí)例,實(shí)現(xiàn)方式:構(gòu)造方法私有化
  2. 必須要自己創(chuàng)建這個(gè)實(shí)例锚贱,實(shí)現(xiàn)方式:在本類中維護(hù)一個(gè)本類對(duì)象(私有仔戈,靜態(tài))
  3. 必須向整個(gè)程序提供這個(gè)實(shí)例,實(shí)現(xiàn)方式:對(duì)外提供公共的訪問方式(getInstance方法拧廊,靜態(tài))

七监徘、包

1、簡(jiǎn)介

把功能相似或相關(guān)的類或接口組織在同一個(gè)包中吧碾,方便類的查找和使用凰盔。 包如同文件夾一樣,不同的包中的類的名字是可以相同的倦春,當(dāng)同時(shí)調(diào)用兩個(gè)不同包中相同類名的類時(shí)户敬,應(yīng)該加上包名加以區(qū)別。因此睁本,包可以避免名字沖突尿庐。包也限定了訪問權(quán)限,擁有包訪問權(quán)限的類才能訪問某個(gè)包中的類呢堰。

2屁倔、使用規(guī)則
- 包中java文件的定義:
    在.java文件的首部, 必須編寫類所屬哪個(gè)包暮胧, 格式:
    package 包名;
- 包的定義:
    通常由多個(gè)單詞組成锐借, 所有單詞的字母小寫, 單詞與單詞之間使用.隔開 往衷,一般命名為“com.公司名.項(xiàng)目名.模塊名....”钞翔。
規(guī)范由來:
    由于Java面向?qū)ο蟮奶匦裕棵鸍ava開發(fā)人員都可以編寫屬于自己的Java Package席舍,為了保障每個(gè)JavaPackage命名的唯一性布轿,在最新的Java編程規(guī)范中,要求開發(fā)人員在自己定義的包名前加上唯一的前綴来颤。由于互聯(lián)網(wǎng)上的域名稱是不會(huì)重復(fù)的汰扭,所以多數(shù)開發(fā)人員采用自己公司在互聯(lián)網(wǎng)上的域名稱作為自己程序包的唯一前綴。例如:com.java.xxx

導(dǎo)入包中的某個(gè)類:
import 包名.類名;

八福铅、main方法詳解:

main()方法一直寫到了今天:
public static void main(String args[])
    以上的各個(gè)參數(shù)的含義如下:
        · public:表示公共的內(nèi)容萝毛,可以被所有操作所調(diào)用
        · static:表示方法是靜態(tài)的,可以由類名稱直接調(diào)用滑黔。java StaticDemo09
        · void:表示沒有任何的返回值操作
        · main:系統(tǒng)規(guī)定好的方法名稱笆包。如果main寫錯(cuò)了或沒有环揽,會(huì)報(bào)錯(cuò):NoSuchMethodError: main
        · String[] args:字符串?dāng)?shù)組,接收參數(shù)的

所有的參數(shù)在執(zhí)行類的時(shí)候以空格進(jìn)行分割庵佣。
java StaticDemo10 1 2 3 4 5 6 7
但是歉胶,要輸入的是以下幾種參數(shù)"hello world"、"hello vince"巴粪、"hello mjw"通今。
因?yàn)橐钥崭穹指睿砸陨系娜M參數(shù)會(huì)當(dāng)做六組參數(shù)輸入肛根,那么此時(shí)如果要想完成有空格的內(nèi)容輸入衡创,則參數(shù)需
要使用""括起來。
java StaticDemo10 "hello world" "hello vince" "hello mjw"

九晶通、final的用法

  • final的意思是最后的璃氢、最終的,它可以修飾類、屬性和方法狮辽。
  • final修飾類時(shí)一也,表明這個(gè)類不能被繼承。final類中的成員變量可以根據(jù)需要設(shè)為final喉脖,但是要注意final類中的所有成員方法都會(huì)被隱式地指定為final方法椰苟。
  • final修飾方法時(shí),表明這個(gè)方法不能被任何子類重寫树叽,因此舆蝴,如果只有在想明確禁止該方法在子類中被覆蓋的情況下才將方法設(shè)置為final。
  • final修飾變量分為兩種情況题诵,一種是修飾基本數(shù)據(jù)類型洁仗,表示數(shù)據(jù)類型的值不能被修改;一種是修飾引用類型,表示對(duì)其初始化之后便不能再讓其指向另一個(gè)對(duì)象性锭。


面向?qū)ο蟾呒?jí)

一赠潦、抽象類

//使用abstract class關(guān)鍵字聲明
//一個(gè)抽象類中可以沒有抽象方法。抽象方法必須寫在抽象類或者接口中草冈。
//抽象方法也要由abstract關(guān)鍵字聲明
abstract class 類名{ // 抽象類
    public abstract void 方法名() ; // 抽象方法她奥,只聲明而未實(shí)現(xiàn)(沒有{}定義的方法體)的方法
}
注意:
  1. 抽象類不可以被實(shí)例化(細(xì)節(jié)都不確定,沒有辦法實(shí)例化)怎棱,無法通過new關(guān)鍵字進(jìn)行構(gòu)造哩俭。但是抽象類可以有構(gòu)造方法,子類繼承抽象類時(shí)拳恋,可以創(chuàng)建抽象類對(duì)象凡资,只不過是JVM幫助創(chuàng)建,由JVM進(jìn)行實(shí)例化诅岩,我們自己無法創(chuàng)建讳苦。子類對(duì)象實(shí)例化的時(shí)候的流程與普通類的繼承是一樣的带膜,都是要先調(diào)用父類中的構(gòu)造方法(默 認(rèn)是無參的)吩谦,之后再調(diào)用子類自己的構(gòu)造方法鸳谜。
  2. 繼承抽象類的子類必須重寫抽象類的所有抽象方法,只要還有一個(gè)抽象的方法沒有重寫實(shí)現(xiàn)式廷,則子類頁也必須聲明為抽象類咐扭。
  3. 抽象類不可以被final聲明:子類無從繼承,該抽象類無法被實(shí)現(xiàn)滑废。
  4. 抽象類必須使用public與protected進(jìn)行修飾蝗肪,默認(rèn)為public,否則private修飾下蠕趁,子類無法繼承薛闪。

二、接口

一個(gè)類中的全部方法都是抽象方法俺陋,全部屬性都是全局常量豁延,那么此時(shí)就可以將這個(gè)類定義成一個(gè)接口。使用interface關(guān)鍵字進(jìn)行聲明:

interface 接口名稱{
    全局常量;
    抽象方法;
}
面向接口編程思想:

接口是定義(規(guī)范腊状,約束)與實(shí)現(xiàn)(名實(shí)分離的原則)的分離诱咏,通過繼承接口來實(shí)現(xiàn)接口中的方法,完成實(shí)現(xiàn)缴挖。

優(yōu)點(diǎn):

  1. 降低程序的耦合性
  2. 易于程序擴(kuò)展
  3. 有利于程序維護(hù)
全局常量和抽象方法簡(jiǎn)寫:

JVM會(huì)自動(dòng)幫助我們完成袋狞,全局常量編寫時(shí), 可以省略public static final 關(guān)鍵字映屋,抽象方法編寫時(shí)苟鸯, 可以省略 public abstract 關(guān)鍵字。

1棚点、全局常量編寫時(shí)倔毙, 可以省略public static final 關(guān)鍵字,例如:
    public static final String INFO = "內(nèi)容" ;
    簡(jiǎn)寫后:
    String INFO = "內(nèi)容" ;
2乙濒、抽象方法編寫時(shí)陕赃, 可以省略 public abstract 關(guān)鍵字, 例如:
    public abstract void print() ;
    簡(jiǎn)寫后:
    void print() ;
接口的實(shí)現(xiàn):

實(shí)現(xiàn)時(shí)使用implements關(guān)鍵字實(shí)現(xiàn)颁股,java中的類只能單繼承類么库,但是可以對(duì)接口進(jìn)行多實(shí)現(xiàn),通過接口實(shí)現(xiàn)別的語言中的多繼承甘有。

class 子類 implements 父接口1,父接口2...{

}
接口的繼承:

允許對(duì)接口進(jìn)行多繼承诉儒,因?yàn)槎际浅橄蟮牟糠郑淮嬖诰唧w實(shí)現(xiàn):

interface C extends A,B{
    
}

注意:一個(gè)接口要想使用亏掀,必須依靠子類實(shí)現(xiàn)接口中的所有抽象方法忱反。

重點(diǎn):接口和抽象類的區(qū)別
  1. 抽象類要被子類繼承泛释,接口要被類實(shí)現(xiàn)。
  2. 接口只能聲明抽象方法温算,抽象類中可以聲明抽象方法怜校,也可以寫非抽象方法。
  3. 接口里定義的變量只能是公共的靜態(tài)的常量注竿,抽象類中的變量是普通變量茄茁。
  4. 抽象類使用繼承來使用, 無法多繼承巩割。 接口使用實(shí)現(xiàn)來使用裙顽, 可以多實(shí)現(xiàn)
  5. 抽象類中可以包含static方法 ,但是接口中不允許(靜態(tài)方法不能被子類重寫宣谈,因此接口中不能聲明靜態(tài)方法)
  6. 接口不能有構(gòu)造方法愈犹,但是抽象類可以有
  7. 可以用接口變量引用一個(gè)實(shí)現(xiàn)了接口的類對(duì)象。

三闻丑、多態(tài)

概念:

多態(tài):就是對(duì)象的多種表現(xiàn)形式漩怎,(多種體現(xiàn)形態(tài))

體現(xiàn):
  1. 父類變量可以引用父類和子類對(duì)象(對(duì)象多態(tài)性,向上轉(zhuǎn)型)梆掸。子類變量引用父類實(shí)例需要實(shí)現(xiàn)強(qiáng)轉(zhuǎn)扬卷。
  2. 方法的重載與重寫(方法的多態(tài))
重載與重寫的區(qū)別:

重載: 一個(gè)類中方法的多態(tài)性體現(xiàn) ,多個(gè)方法簽名酸钦,編譯器來選擇最合適的那個(gè)怪得。

重寫: 子父類中方法的多態(tài)性體現(xiàn)。調(diào)用繼承鏈上最近的子父類同名方法卑硫。

對(duì)象的類型轉(zhuǎn)換:
· 向上轉(zhuǎn)型:將子類實(shí)例變?yōu)楦割悓?shí)例
    |- 格式:父類 父類對(duì)象 = 子類實(shí)例 徒恋;
· 向下轉(zhuǎn)型:將父類實(shí)例變?yōu)樽宇悓?shí)例
    |- 格式:子類 子類對(duì)象 = (子類)父類實(shí)例 ;

四欢伏、insatnceof方法

給自定義類重寫equals方法時(shí)調(diào)用入挣,判斷某個(gè)對(duì)象是否為某個(gè)類的實(shí)例,返回boolean類型的值硝拧。

五径筏、Object類

所有類的父類,自定義類繼承自O(shè)bject障陶,需要重寫toString與equals和hashcode三個(gè)方法滋恬,后兩個(gè)配合使用。

使用Object可以接收任意的引用數(shù)據(jù)類型抱究。(多態(tài))

toString
建議重寫Object中的toString方法恢氯。 此方法的作用:返回對(duì)象的字符串表示形式。
Object的toString方法, 返回對(duì)象的內(nèi)存地址
equals
建議重寫Object中的equals(Object obj)方法勋拟,此方法的作用:指示某個(gè)其他對(duì)象是否“等于”此對(duì)象勋磕。
Object的equals方法:實(shí)現(xiàn)了對(duì)象上最具區(qū)別的可能等價(jià)關(guān)系; 也就是說,對(duì)于任何非空引用值x和y 敢靡,當(dāng)且僅當(dāng)x和y引用同一對(duì)象( x == y具有值true )時(shí)挂滓,此方法返回true 。
equals方法重寫時(shí)的五個(gè)特性:
    自反性 :對(duì)于任何非空的參考值x 醋安, x.equals(x)應(yīng)該返回true 杂彭。
    對(duì)稱性 :對(duì)于任何非空引用值x和y 墓毒, x.equals(y)應(yīng)該返回true當(dāng)且僅當(dāng)y.equals(x)回報(bào)true 吓揪。
    傳遞性 :對(duì)于任何非空引用值x , y和z 所计,如果x.equals(y)回報(bào)true個(gè)y.equals(z)回報(bào)true 柠辞,然后
    x.equals(z)應(yīng)該返回true 。
    一致性 :對(duì)于任何非空引用值x和y 主胧,多次調(diào)用x.equals(y)始終返回true或始終返回false 叭首,前提是未修改對(duì)象
    上的equals比較中使用的信息。
    非空性 :對(duì)于任何非空的參考值x 踪栋, x.equals(null)應(yīng)該返回false 焙格。

六、內(nèi)部類(非重點(diǎn))

概念:定義在別的類內(nèi)部的類夷都。由于每個(gè)類都會(huì)產(chǎn)生一個(gè).class文件眷唉,其中包含了如何創(chuàng)建該類型的對(duì)象的全部信息,那么囤官,如何表示內(nèi)部類的信息呢?可以使用美元符號(hào)來表示冬阳,比如OuterClass美元符號(hào)InnerClass.class。這里InnerClass就是OuterClass 的一個(gè)內(nèi)部類党饮。也就是說肝陪,每個(gè)內(nèi)部類都能獨(dú)立地繼承一個(gè)(接口的)實(shí)現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn)刑顺,對(duì)于內(nèi)部類都沒有影響氯窍。這也是隱藏了內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。內(nèi)部類擁有外部類的訪問權(quán)蹲堂。在這段代碼中狼讨,InnerClass就是OuterClass 的一個(gè)內(nèi)部類。也就是說贯城,每個(gè)內(nèi)部類都能獨(dú)立地繼承一個(gè)(接口的)實(shí)現(xiàn)熊楼,所以無論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒有影響。這也是隱藏了內(nèi)部實(shí)現(xiàn)細(xì)節(jié)鲫骗。內(nèi)部類擁有外部類的訪問權(quán)犬耻。內(nèi)部類不僅僅能夠定義在類的內(nèi)部,還可以定義在方法和作用域內(nèi)部执泰,這種被稱為局部?jī)?nèi)部類枕磁,除此之外,還有匿名內(nèi)部類术吝、內(nèi)部類可以實(shí)現(xiàn) Java 中的 多重繼承计济。下面是定義內(nèi)部類的方式

1、成員內(nèi)部類
class Outer {
    private double x = 0;
    public Outer(double x) {
        this.x = x;
    }
    class Inner { //內(nèi)部類
        private double x = 1.0
        public void say() {
            System.out.println("x="+x);//默認(rèn)使用的是內(nèi)部類的x,打印1.0
             System.out.println("x="+Outer.this.x);//使用的是外部類的x,打印0            
        }
    }
}

特點(diǎn): 成員內(nèi)部類可以無條件訪問外部類的所有成員屬性和成員方法(包括private成員和靜態(tài)成員)排苍,因?yàn)橥獠款惒粍?chuàng)建對(duì)象沦寂,內(nèi)部類是實(shí)現(xiàn)不了的,當(dāng)內(nèi)部類可以使用時(shí)淘衙,外部類的成員與方法都已經(jīng)有了传藏。

Outer o = new Outer();
Outer.Inner i = o.new Inner();//使用內(nèi)部類

當(dāng)成員內(nèi)部類擁有和外部類同名的成員變量或者方法時(shí),會(huì)發(fā)生隱藏現(xiàn)象彤守,即默認(rèn)情況下訪問的是成員內(nèi)部類的成員毯侦。

如果要訪問外部類的同名成員,需要以下面的形式進(jìn)行訪問:

**外部類.this.成員變量 **

外部類.this.成員方法

2具垫、局部?jī)?nèi)部類

局部?jī)?nèi)部類是定義在一個(gè)方法或者一個(gè)作用域里面的類侈离,它和成員內(nèi)部類的區(qū)別在于局部?jī)?nèi)部類的訪問僅限于方法內(nèi)或 者該作用域內(nèi)。

注意:局部?jī)?nèi)部類就像是方法里面的一個(gè)局部變量一樣筝蚕,是不能有public卦碾、protected、private以及static修飾符的饰及。

3蔗坯、匿名內(nèi)部類
匿名內(nèi)部類由于沒有名字,所以它的創(chuàng)建方式有點(diǎn)兒奇怪燎含。創(chuàng)建格式如下:
    new 父類構(gòu)造器(參數(shù)列表)|實(shí)現(xiàn)接口()
    {
        //匿名內(nèi)部類的類體部分
    }
在這里我們看到使用匿名內(nèi)部類我們必須要繼承一個(gè)父類或者實(shí)現(xiàn)一個(gè)接口宾濒,當(dāng)然也僅能只繼承一個(gè)父類或者實(shí)現(xiàn)一個(gè)接口。同時(shí)它也是沒有class關(guān)鍵字屏箍,這是因?yàn)槟涿麅?nèi)部類是直接使用new來生成一個(gè)對(duì)象的引用绘梦。當(dāng)然這個(gè)引用是隱式的。

注意:

  1. 使用匿名內(nèi)部類時(shí)赴魁,我們必須是繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口卸奉,但是兩者不可兼得,同時(shí)也只能繼承一個(gè)類或 者實(shí)現(xiàn)一個(gè)接口颖御。
  2. 匿名內(nèi)部類中是不能定義構(gòu)造函數(shù)的榄棵。
  3. 匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法。
  4. 匿名內(nèi)部類為局部?jī)?nèi)部類,所以局部?jī)?nèi)部類的所有限制同樣對(duì)匿名內(nèi)部類生效疹鳄。
  5. 匿名內(nèi)部類不能是抽象的拧略,它必須要實(shí)現(xiàn)繼承的類或者實(shí)現(xiàn)的接口的所有抽象方法。
  6. 只能訪問final型的局部變量(單獨(dú)編譯為字節(jié)碼文件瘪弓,如果不是final垫蛆,會(huì)造成引用與拷貝不一致的問題)
4、靜態(tài)內(nèi)部類

靜態(tài)內(nèi)部類也是定義在另一個(gè)類里面的類腺怯,只不過在類的前面多了一個(gè)關(guān)鍵字static袱饭。 靜態(tài)內(nèi)部類是不需要依賴于外部類對(duì)象的(不需要先創(chuàng)建外部類實(shí)例),這點(diǎn)和類的靜態(tài)成員屬性有點(diǎn)類似呛占,并且它不能使用外部類的非static成員變量或者方法(靜態(tài)不能訪問非靜態(tài))虑乖,因?yàn)榇藭r(shí)內(nèi)部已經(jīng)有了,外部可能還沒有栓票。

public class Test {
    public static void main(String[] args) {
        Outter.Inner inner = new Outter.Inner();
    }
}
class Outter {
    public Outter() {
    }
    static class Inner {
        public Inner() {
        }
    }
}
    

七决左、包裝類

自動(dòng)裝箱與自動(dòng)拆箱:
Float f = 10.3f ; // 自動(dòng)裝箱
float x = f ; // 自動(dòng)拆箱
System.out.println(f * f) ; // 直接利用包裝類完成
System.out.println(x * x) ; // 直接利用包裝類完成
字符串裝換:
//使用包裝類還有一個(gè)很優(yōu)秀的地方在于:可以將一個(gè)字符串變?yōu)橹付ǖ幕緮?shù)據(jù)類型愕够,此點(diǎn)一般在接收輸入數(shù)據(jù)上使用較多走贪。
//在Integer類中提供了以下的操作方法:
public static int parseInt(String s) :將String變?yōu)閕nt型數(shù)據(jù)
//在Float類中提供了以下的操作方法:
public static float parseFloat(String s) :將String變?yōu)镕loat
//在Boolean 類中提供了以下操作方法:
public static boolean parseBoolean(String s) :將String變?yōu)閎oolean

八、可變參數(shù)

返回值類型 方法名稱(數(shù)據(jù)類型…參數(shù)名稱){
    //參數(shù)在方法內(nèi)部 惑芭, 以數(shù)組的形式來接收
}

int calculateSum(int...nums){//nums為長(zhǎng)度不限的可變參數(shù)坠狡,注意可變參數(shù)一定在參數(shù)列表的最后
    int sum = 0;
    for(int num:nums){
        n += num;
    }
    return sum;
}

九、遞歸

函數(shù)要調(diào)用自身遂跟,程序要有出口逃沿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市幻锁,隨后出現(xiàn)的幾起案子凯亮,更是在濱河造成了極大的恐慌,老刑警劉巖哄尔,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件假消,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岭接,警方通過查閱死者的電腦和手機(jī)富拗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸣戴,“玉大人啃沪,你說我怎么就攤上這事≌” “怎么了创千?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我追驴,道長(zhǎng)寓涨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任氯檐,我火速辦了婚禮戒良,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冠摄。我一直安慰自己糯崎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布河泳。 她就那樣靜靜地躺著沃呢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拆挥。 梳的紋絲不亂的頭發(fā)上薄霜,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音纸兔,去河邊找鬼惰瓜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛汉矿,可吹牛的內(nèi)容都是我干的崎坊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼洲拇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼奈揍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起赋续,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤男翰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后纽乱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛾绎,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年迫淹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秘通。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敛熬,死狀恐怖肺稀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情应民,我是刑警寧澤话原,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布夕吻,位于F島的核電站,受9級(jí)特大地震影響繁仁,放射性物質(zhì)發(fā)生泄漏涉馅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一黄虱、第九天 我趴在偏房一處隱蔽的房頂上張望稚矿。 院中可真熱鬧,春花似錦捻浦、人聲如沸晤揣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昧识。三九已至,卻和暖如春盗扒,著一層夾襖步出監(jiān)牢的瞬間跪楞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工侣灶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留甸祭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓炫隶,卻偏偏與公主長(zhǎng)得像淋叶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伪阶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359