2023年java基礎知識點總結_第1頁
2023年java基礎知識點總結_第2頁
2023年java基礎知識點總結_第3頁
2023年java基礎知識點總結_第4頁
2023年java基礎知識點總結_第5頁
已閱讀5頁,還剩19頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

CreatedbyAlwenon2023/5/14.java是面向對象的程序設計語言;類可被認為是一種自定義的數(shù)據(jù)類型,可以使用類來定義變量,所有使用類定義的變量都是引用變量,它們將會引用到類的對象。類用于描述客觀世界里某一類對象的共同特性,而對象則是類的具體存在,java程序使用類的構造器來創(chuàng)建該類的對象。Ajava也支持面向對象的三大特性:封裝、繼承、和多態(tài)。java提供了private>protected>和public三個訪問控制修飾符來實現(xiàn)良好的封裝,提供了extends關鍵字讓子類繼承父類,子類繼承父類就可以繼承到父類的成員變量和和方法,假如訪問控制允許,子類實例可以直接調(diào)用父類里定義的方法。繼承是實現(xiàn)類復用的重要手段。使用繼承關系來實現(xiàn)復用時,子類對象可以直接賦給父類變量,這個變量具有多態(tài)性。面向對象的程序設計過程中有兩個重要的概念:類(Class)和對象(object,也被稱為實例,instance)o類可以包含三種最常見的成員:構造器、成員變量、和方法。a構造器用于構造該類的實例,java語言通過new關鍵字類調(diào)用構造器,從而返回該類的實例。構造器是一個類創(chuàng)建對象的主線途徑,假如一個類沒有構造器,這個類通常無法創(chuàng)建實例。因此java語言提供了一個功能:假如程序員沒有為一個類編寫構造器,則系統(tǒng)會為該類提供一個默認的構造器,這個構造器總是沒有參數(shù)的。一旦程序員為一個類提供了構造器,系統(tǒng)將不再為該類提供構造器。構造器用于對類實例進行初始化操作,構造器支持重載,假如多個重載的構造器里包含了相同的初始化代碼,則可以把這些初始化代碼放置在普通初始化塊里完畢,初始化塊總在構造器執(zhí)行之前被調(diào)用。靜態(tài)初始化塊代碼用于初始化類,在類初始化階段被執(zhí)行。假如繼承樹里某一個類需要被初始化時,系統(tǒng)將會同時初始化該類的所有父類。構造器修飾符:可以是public、protected、private其中之一,或者省略構造器名:構造器名必須和類名相同。注意:構造器既不能定義返回值類型,也不能使用void聲明構造器沒有返回值。假如為構造器定義了返回值類型,或使用void聲明構造器沒有返回值,編譯時不會犯錯,但java會把這個所謂的構造器當成方法來解決一一它就不再是構造器。超事實上類的構造器是有返回值的,當使用new關鍵字來調(diào)用構造器時,構造器返回該類的實例,可以把這個類的實例當成構造器的返回值。因此構造器的返回值類型總是當前類,無須定義返回值類型。不要在構造器里顯式的使用return來返回當前類的對象,由于構造器的返回值是隱式的。占java類名必須是由一個或多個故意義的單詞連綴而成的,每個單詞首字母大寫,其他字母所有小寫,單詞與單詞之間不要使用任何分隔符。A.查找當前類中是否包含名為a的成員變量.查找a的直接父類中是否包含名為a的成員變量,一次上溯a的所有父類,直到java.Iang.Object類,假如最終不能找到名為a的成員變量,則系統(tǒng)出現(xiàn)編譯錯誤。假如被覆蓋的是類變量,在子類的方法中則可以通過父類名作為調(diào)用者來訪問被覆蓋的類變量當程序創(chuàng)建一個子類對象時,系統(tǒng)不僅會為該類中定義的實例變量分派內(nèi)存,也會為它從父類繼承得到的所有實例變量分派內(nèi)存,即使子類定義了與父類中同名的實例變量。假如在子類里定義了與父類中已有變量同名的變量,那么子類中定義的變量會隱藏父類中定義的變量。注意不是完全覆蓋,因此系統(tǒng)在創(chuàng)建子類對象時,仍然會為父類中定義的、被隱藏的變量分派內(nèi)存空間。publicc1assParent{apublicStringtag="he11oworld”;}publicclassDerivedextendsParent{a//定義一個私有的tag實例變量來隱藏父類的tag實例變量privateStringtag="abc"publicclassHideTest仙publiestaticvoidmain(String[]args){aDerivedd=newDerived();A//程序不可訪問d的私有變量tag,所以會出現(xiàn)編譯錯誤//System.out.printin(d.tag);//將d變量顯式的向上轉型為Parent后,即可訪問tag實例變量\System.out.printIn(((Parent)d).tag);a}a)調(diào)用父類構造器:子類不會獲得父類的構造器,但子類構造器里可以調(diào)用父類構造器的初始化代碼。在一個構造器里調(diào)用另一個重載的構造器使用this調(diào)用來完畢,在子類構造器中調(diào)用父類構造器使用SUper調(diào)用來完畢。publieclassBase{a..publicdoublesize;publieStringname;A.publicBase(doublesize,Stringname){this.size=size;=name;a}a}publicclassSubextendsBase{apublicStringcolor;apublicSub(doublesize,Stringname,Stringcolor){a//通過super調(diào)用父類構造器的初始化過程'super(size,name);this,color=color;}apublicstaticvoidmain(String[]args){aSubs=newSub(5.6,〃測試〃,”red〃);System.out.print1n(s.size+”,"+s?name+”,"+s?co1or)})Super調(diào)用的是其父類的構造器,而this調(diào)用的是同一個類中重載的構造器;因此,使用super調(diào)用父類的構造器也必須出現(xiàn)在子類構造器執(zhí)行體的第一行,所以this調(diào)用和super調(diào)用不會同時出現(xiàn)。當調(diào)用子類構造器來初始化子類對象時,父類構造器總會在子類構造器之前執(zhí)行;不僅如此,執(zhí)行父類構造器時,系統(tǒng)會再次上溯執(zhí)行其父類的構造器……依次類推,創(chuàng)建任何java對象,最先執(zhí)行的總是java.lang.Object類的構

造器。publieclassCreature{apublicCreature(){aSystem,onprintln(n無參”);.}}publicclassAnimalextendsCreature{apub1icAnimal(Stringname){aSystem.out.print1n("Animal帶一個參數(shù)的構造器"+name)}apublicAnimal(Stringname,intage){//this調(diào)用同一個重載構造器二this(name);S1n("Anima1帶兩個參數(shù)的構造器"+age);.}}publicc1assWolfextendsAnimal{publicWolf(){asuper("灰太狼",4);aSystem.out.printin("wolf無參構造器”);)publiestaticvoidmain(String[]args){Wolfwf=newWolf();//雖然main方法只創(chuàng)建了一個Wolf對象,但系統(tǒng)在底層完畢了復雜的操作,運營將會得到//無笏〃Anima1帶一個參數(shù)的構造器灰太狼//Anima1帶兩個參數(shù)的構造器4//wolf無參構造器口}}創(chuàng)建任何對象總是從該類所在繼承樹最頂層類的構造器開始執(zhí)行,然后依次向下執(zhí)行,最后才執(zhí)行本類的構造器。假如某個父類通過this調(diào)用了同類中重載的構造器,就會依次執(zhí)行此父類的多個構造器。4?7多態(tài):Java引用變量有兩個類型:一個是編譯時類型,一個是運營時類型。編譯時類型由聲明該變量時使用的類型決定,運營時類型由實際賦給該變量的對象決定。假如編譯時類型和運營時類型不一致,就也許出現(xiàn)所謂的多態(tài)。publicclassBaseC1ass{apublicintbook=6;ASystem.publicclassBaseC1ass{apublicintbook=6;ASystem.out.println("父類的普通方法");}apub1icvoidtest(){System.out.println("父類被覆蓋的方法”);)}publicclassSubC1assextendsBaseClass{//重寫定義一個book實例變量隱藏父類的book實例變量publicStringbook="abc";apublicvoidtest(){a類的覆蓋父類的方法〃);}publicvoidsub(){System.out.printin("子類的普通方法”)鴻)pub1icstaticvoidmain(String口args){//編譯時類型和運營時類型完全同樣,因此不存在多態(tài)口publicvoidbase(){aSystem.out.println("子BaseClassbc=newBaseC1a〃輸出父類bc對象的成員變量值:6口〃輸出父類bc對象的成員變量值:〃輸出父類bc對象的成員變量值:6口System.out.printIn(be.book);be.base();//編譯時類型和運營時類型完全同樣,因此不存在多態(tài)SubClasssbc=newSubClass();a//輸出子類對象sbc的成員變量值:abc口System,out.print1n(sbe.book);asbe.test();sbc.sub();A//下面調(diào)用將執(zhí)行從父類繼承到的base()方法sbc.base();//編譯時類型和運營時類型不同樣,發(fā)生多態(tài)發(fā)生'BaseC1assployBc=newSubClass();〃訪問的是父類對象的實例變量^System.oat.println(p1oyBc.book);A//執(zhí)行從父類繼承到的base。方法p1oyBc.base();//調(diào)用將執(zhí)行當前類的test()方法^ployBc.test();//ployBe.sub();由于編譯時類型是BaseClass,沒有提供sub()方法,所以編譯會出現(xiàn)錯誤由于子類是一種特殊的父類,因此java允許把一個子類對象直接賦給一個父類引用變量,無須任何類型轉換,或者被稱為向上轉型,向上轉型由系統(tǒng)自動完全。a對象的實例變量不具有多態(tài)性。注:引用變量在編譯階段只能調(diào)用其編譯時類型所具有的方法,但運營時則執(zhí)行它運營時類型所具有的方法。因此在編寫Java代碼時,引用變量只能調(diào)用聲明該變量時所用類里包含的方法。例如:0bjectp=newPerson。代碼定義了一個變量p,則這個p只能調(diào)用Object類的方法,而不能調(diào)用Person類里的方法。假如需要讓這個引用變量調(diào)用它運營時類型的方法,則必須把它強制類型轉化成運營時的類型,強制類型轉換符需要借助于類型轉換運算符,用法是(type)variable強制類型轉換需要注意:基本類型之間的轉換只能在數(shù)值類型之間進行,這里所說的數(shù)值類型涉及,整數(shù)型、字符型和浮點型;但數(shù)值類型和布爾類型之間不能進行類型轉換。引用類型之間的轉換只能在具有繼承關系的兩個類型之間進行,假如是兩個沒有任何繼承關系的類型,則無法進行類型轉換??紤]到強制類型轉換時也許出現(xiàn)異常,因此進行類型轉換之前應先通過instanceof運算符來判斷是否可以成功轉換。注意:當把子類對象賦給父類引用變量時,被稱為向上轉型,這種轉型總是可以成功的,這也從另一個側面證實了子類是一種特殊的父類。這種轉型只是表白這個引用變量的編譯時類型是父類,但實際執(zhí)行它的方法時,仍然表現(xiàn)出子類對象行為方式。但把一個父類對象賦給子類引用變量時,就需要進行強制類型轉換,并且還也許在運營時產(chǎn)生ClassCastException異常,使用instanceof運算符可以讓強制類型轉換更安全。Instanceof運算符:Instanceof運算符前一個操作數(shù)通常是一個引用類型變量,后一個操作數(shù)通常是一個類(也可以是接口),它用于判斷前面的對象是否是后面的類,或者其子類、實現(xiàn)的實例。假如是,則返回ture,否則返回false.在使用instanceof運算符時需要注意:instanceof運算符前面操作數(shù)的編譯時類型要么與后面的類相同,要么與后面的類具有父子繼承關系,否則會引起編譯錯誤。publicclassinstanceofTest(publicstaticvoidmain(String1]args){〃聲明hello時使用Object類,J/HJhe11oObjectU//Object是所有類的父類,但he1lo變量的實際類型是StringUObjecthello="he1lo”;System,out.print1n((helloinstanceofObject));〃String和Object類存在繼承關系,可以進行instaneeof運算,返回trueSystem,out.print1n((helloinstanceofString));//Math和Object類存在繼承關系,可以進行instanceof運算,返回falseSystem.out.print1n((hel1oinstanceofMath));//String實現(xiàn)了Comparabel接口,所以返回true口System.out.println((he11oinstanceofComparable));Stringa="hello”;//String類和Math類沒有繼承關系,所以下面的代碼編譯無法通過//System.out.printIn((ainstanceofMath));□}}4.8初始化塊:初始化塊是一段固定執(zhí)行的代碼,它不能接受任何參數(shù)。因此初始化塊對同一個類的所有對象所進行的的初始化解決完全相同。假如兩個構造器中有相容的初始化代碼,且這些初始化代碼無須接受參數(shù),就可以把它們放在初始化塊中定義。當創(chuàng)建java對象時,系統(tǒng)總是先調(diào)用該類里定義的初始化塊,相同類型的初始化塊之間按順序執(zhí)行。初始化塊在執(zhí)行構造器之前執(zhí)行。與構造器類型,創(chuàng)建一個java對象時,不僅會執(zhí)行該類的普通初始化塊和構造器,并且系統(tǒng)會一直上溯到java.1ang.Object類,先執(zhí)行java.1ang.Object類的初始化塊,再開始執(zhí)行java.1ang.Object的構造器,依次向下執(zhí)行其子類的初始化塊,再開始執(zhí)行其子類的構造器…最后才執(zhí)行該類的初始化塊和構造器,返回該類的對象。靜態(tài)初始化塊:假如定義初始化塊時使用了static修飾符,則這個初始化塊就變成了靜態(tài)初始化塊,也被稱為類初始化塊(普通初始化塊負責對對象執(zhí)行初始化,類初始化塊則負責對類進行初始化)。靜態(tài)初始化塊總是類相關的,系統(tǒng)將在類初始化階段執(zhí)行靜態(tài)初始化塊,而不是在創(chuàng)建對象時才執(zhí)行。因此靜態(tài)初始化塊總是比普通初始化塊先執(zhí)行。通常靜態(tài)初始化塊用于對類變量執(zhí)行初始化解決O與普通初始化塊類型,系統(tǒng)在類初始化階段執(zhí)行靜態(tài)初始化塊時,不僅會執(zhí)行本類的靜態(tài)初始化塊,并且還會一直上溯到java.lang.Object類,從最高父類開始一直到本類結束,依次執(zhí)行每個類中的靜態(tài)初始化塊。publicclassTest{apub1icstaticvoidmain(String[]args){newLeaf()newLeaf();}}M1assRootbstatic{aSystem.o〃力println("Root的靜態(tài)初始化塊");?}A(System.out.printin("Root的初始化塊");}apublieRoot(){aSystem.0〃1.println("Root的無參構造器”);}a}ac1assMidextendsRoot{static{a.System.out.printin(nMid的靜態(tài)初始化塊”);)(System.out.printin("Mid的初始化塊“);)publicMid(){System.out.printIn(Z,Mid的無參構造器“);.publicMid(Stringmsg){//通過this調(diào)用同一類中重載的構造器口this();System.out.rint1n("Mid的帶有參數(shù)的構造器“);?}}classLeafextendsMid{static{aSystem.0〃。.print1n("Leaf的靜態(tài)初始化塊”);.}(System.out.printin("Leaf的初始化塊”);}pub1icLeaf(){super(“abe”);System.out.print1n("執(zhí)行Leaf的構造器“);a})Root的靜態(tài)初始化塊Mid的靜態(tài)初始化塊Leaf的靜態(tài)初始化塊Root的初始化塊Root的無參構造器Mid的初始化塊Mid的無參構造器Mid的帶有參數(shù)的構造器Leaf的初始化塊執(zhí)行Leaf的構造器Root的初始化塊Root的無參構造器Mid的初始化塊Mid的無參構造器Mid的帶有參數(shù)的構造器Leaf的初始化塊執(zhí)行Leaf的構造器類初始化階段,先執(zhí)行最頂層父類的靜態(tài)初始化塊,然后依次向下,直到執(zhí)行當前類的初始化塊。對象初始化階段,先執(zhí)行最頂層父類的初始化塊、最頂層父類的構造器,然后依次向下,直到執(zhí)行當前類的初始化塊、當前類的構造器Java系統(tǒng)加載并初始化某個類時,總是保證該類的所有父類(涉及直接父類和間接父類)所有加載并進行初始化。靜態(tài)初始化塊和靜態(tài)成員變量的執(zhí)行順序與在源程序中排列順序相同。第五章面向對象下5.1java增強的包裝類為了解決8種基本類型的變量不能當成Object類型變量使用的問題,java提供了包裝類的概念。除了int和char有點例外,其他的基本數(shù)據(jù)類型相應的包裝類都是將其首字母大寫即可。自動裝箱和自動拆箱用法:publicclassAutoBoxingUnboxing{publicstaticvoidmain(String[]args){a〃直接把一個基本類型變量賦給Integer對象IntegerinObj=5;//直接把一"個boolean類型變量賦給Object類型變最'0bjectboolObj=true;//直接把一個Integer對象賦給int類型變量intit二inObj;if(boolObjinstanceofBoolean){//^EObject對象強制類型轉換為Boolean類型,再賦給boolean變量booleanb=(Boolean)bool0bj;aSystem.out.println(b);a}}}包裝類還可實現(xiàn)基本類型變量和字符串之間的轉換。把字符串類型的值轉換為基本類型的值有兩種方式:1)運用包裝類提供的parseXxx(Strings)靜態(tài)方法2)運用包裝類提供的Xxx(Strings)構造器String類提供了多個重載的value。f()方法,用于將基本類型變量轉換成字符串。publicclassPrimitive2String{apub1icstaticvoidmain(String[]args){△StringintStr="123";//把一個特定的字符串轉換成int變量Lintit1=Integer.parse/〃方(intStr);aintit2=newInteger(intStr);aSystem,out.printIn(it2);aStringfloatStr="4.56〃;a//把一個特定的字符串轉換成float變量floatftl=Float.parseF1oat(f1oatStr);afloatft2=newFloat(f1oatStr);〃把一個float變量轉換成String變量JStringftStr=String,value0f(2.345f);aSystem,out.print1n(ftStr);a//把一個double變量轉換成String變量StringdbStr=String.vaJue0f(3.344);System.out.print1n(dbStr);a//把一個boolean變量轉換成String變S2StringboolStr=String.valueOf(true);System.ou/■.print1n(booIStr.toUppercase());假如希望把基本類型變量轉換成字符串,尚有一種更簡樸的方法:將基本類型變量和””進行連接運算,系統(tǒng)會自動把基本類型變量轉換成字符串O雖然包裝類型的變量時引用數(shù)據(jù)類型,但包裝類的實例可以與數(shù)值類型的值進行比較,這種比較是直接取出包裝類實例所包裝的數(shù)值來進行比較的。publicclassTestDemo{apublicstaticvoidmain(String[]args){aIntegera=newInteger(6)?冷System,out.println(a>5);//兩個包裝類實例進行比較時,只有兩個包裝類引用指向同一個對象時才返回tur尤System..out.print1n(newInteger(2)二二newInteger(2));a}a}系統(tǒng)把一個一128-127之間的證書自動裝箱成Integer實例,并放入了一個名為cache的數(shù)組中緩存起來。假如以后把一個一128—127之間的整數(shù)自動裝箱成一個Integer實例時,事實上是直接指向相應的數(shù)組元素,因此一128—127之間的同一個整數(shù)自動裝箱成Integer實例時,永遠都是引用eache數(shù)組的同一個數(shù)組元素,所以它們都相等。但假如整數(shù)不在這個范圍內(nèi),則會重新創(chuàng)建一個Integer實例。pub1icclassTestDmo2{apublicstaticvoidmain(String口args){Integera=2;Integerb=2;aSystem.out.println(a==b);//truIntegerbiga=128;aIntegerbigb=128;aSystem.out.println(biga==bigb);//false)}5.2解決對象對象打印的誤區(qū):pub1icclassPrint0bject{apublicstaticvoidmain(String[]args){aPersonp=newPerson("Peter");〃假如想打E[]p對象的內(nèi)容,下面兩種方法都不可以,打出來的都是地址值口//Object類提供的toString()方法總是返回該對象實現(xiàn)類的“類名+@+hashCode”的值System.out.printIn(p);aSystem.out.print1n(p.toString());}a}aclassPerson{privateStringname*publicPerson(Stringname){athis,name=name;重寫toString。方法,通過重寫,就可以讓系統(tǒng)在打印Apple對象時打印該對象的“自我描述”內(nèi)容publicclassToStringTest{publicstaticvoidmain(String[]args){Applea=newApple("red”,100);a//打印Apple對象System.out.println(a);)}c1assApple{△privateStringcolor;aprivatedoubleweight;//提供有參數(shù)的構造器publicApple(Stringcolor,doubleweight){athis,color=color;this,weight=weight;)publicStringgetCo1or(){returncolor;}pub1icvoidsetColor(Stringco1or){athis.color=color;}publicdoublegetWeight(){areturnweight;a}publicvoidsetWeigth(doub1eweigth){this.weight=weight;)一//重寫toString。方法CpublieStringtoString(){areturncolor+”,"+weight;a)}2.2==和equals方法Java中測試兩個變量是否相等有兩種方式,一種是運用==運算符,一種是運用equa1s()方法。當使用==來判斷兩個變量是否相等時,假如兩個變量是基本類型變量,且都是數(shù)值類型(不一定規(guī)定數(shù)據(jù)類型嚴格相同),則只要兩個變量的值相等,就將返回true.對于兩個引用類型變量,只有他們指向同一個對象時,==判斷才會返回trueo==不可用于比較類型上沒有父子關系的兩個對象。publicc1assEqualTest{publicstaticvoidmain(String[]args){aintit=65;af1oatf1=65.0f;System.out.println(“65和65.0是否相等?”+(it==fl));//truecharch='A';System.o〃1.printIn("65和A是否相等?"+(it==ch));//trueStringstrl=newString("he11o");aStringstr2=newString("hello”);System,out.println(Mstri和str2是否相等?”+(strl==str2));//falseSystem.out.printin("strl是否equalsstr2?”+(stri.equa1s(str2)));//true}當Java程序直接使用形如"hel1o”的字符串直接量(涉及可以在編譯時就計算出來的字符串值)時,JVM將會使用常量池來管理這些字符串;當使用newStringChello")時,JVM會先使用常量池來管理“hel1?!敝苯恿?,再調(diào)用String類的構造器來創(chuàng)建一個新的String對象,新創(chuàng)建的String對象被保存在堆內(nèi)存中。換句話說,newString("hell。")一共產(chǎn)生了兩個字符串對象。publieclassStringCompareTest{apubliestaticvoidmain(String[]args){a〃sl直接引用常量池中的“瘋狂java"匚Stringsi二"瘋狂java”;Strings2="瘋狂",冷Strings3="java";a//s4s5后面的字符串值可以在編譯時就擬定下來,它們都直接引用常量池中的“瘋狂java”「Strings4二〃瘋狂〃+〃java〃;aStrings5二"瘋〃+"狂〃+”java//s6后面的字符串值不能在編譯時就擬定下來Strings6=s2+s3;a//s7引用堆內(nèi)存中新創(chuàng)建的String對象匚Strings7二newString("瘋狂java");aSystem.out.println(sl==s4);//trucSystem.t.println(sl==s5);//trueJSystem.out.print1n(sl==s6);//falseLSystem,out.printin(s1==s7);//faIse}a}JVM常量池保證相同的字符串直接量只有一個,不會產(chǎn)生多個副本。String已經(jīng)重寫了Object的equals。方法,String的equa1s()方法判斷兩個字符串相等的標準是:只要兩個字符串所包含的字符序列相同,通過equals。比較將返回true,否則返回false類成員不能訪問實例成員假如一個類始終只能創(chuàng)建一個實例,則這個類被稱為單例類publicclassSing1etonTest{apublicstaticvoidmain(String[]args){//創(chuàng)建Singleton對象不能通過構造器,只能通過getlnstance方法得到實例1Sing1etons1=Singleton.getinstance();aSing1etons2=Sing1eton.getlnstance();System.out.println(sl==:s2);a}J^classSingleton{a//使用一個類變量來緩存曾經(jīng)創(chuàng)建的實例privatestaticSingletoninstance\//對構造器使用Private修飾,隱藏該構造器privateSing1eton(){}◎//提供一個靜態(tài)方法,用于返回Sing1eton實例//該方法可以加入自定義控制,保證只產(chǎn)生一個Singleton對象publicstaticSingletongetlnstance(){a//假如Instance為Nu11,,則表白還不曾創(chuàng)建singleton對象//假如intstance不為null,則表白已經(jīng)創(chuàng)建了Sing1eton對象,將不會重新創(chuàng)建新的實例口if(//7577ce==nu11){ainstance=ne^iSingleton();}areturninstance;a}5.4final修飾符Fina1修飾的變量不可被改變,一旦獲得了初始值,該final變量的值就不能被重新賦值。因此java語法規(guī)定:final修飾的成員變量必須由程序員顯式的指定初始值。Final修飾的類變量、實例變量能指定初始值的地方如下:類變量:必須在靜態(tài)初始化塊中指定初始值或聲明該類型變量時指定初始值,并且只能在兩個地方的其中之一指定實例變量:必須在非靜態(tài)初始化塊、聲明該實例變量或構造器中指定初始值,并且只能在三個地方的其中之一指定。實例變量不能在靜態(tài)初始化塊中指定初始值,由于靜態(tài)初始化塊時靜態(tài)成員,不可訪問實例變量——非靜態(tài)成員;類變量不能在普通初始化塊中指定初始值,由于類變量在類初始化階段已經(jīng)被初始化了,普通初始化塊不能對其重新賦值。publicclassFinaIVariableTest{a//定義成員變量時指定默認值,分finalinta=6;〃下面這三個變量將在構造器或初始化塊中指定初始值3finalStringstr;fina1intc;afinalstaticdoubled;a//ch既沒有指定默認值,有沒有在初始化塊、構造器中指定初始值Q7finalcharc/i;Q//初始化塊,對沒有指定默認值的實例變量指定初始值口{a//在初始化塊中為實例變量指定初始值,合法□str=z,helloz,;//定義a實例變量時,已經(jīng)指定了默認值,不能重新為a賦值//a=9;}static{//在靜態(tài)初始化塊中為類變量指定初始值,合法15.6;}pub1icFinalVariableTest(){//str在初始化塊中已定義初始值,不可重新賦值//str=〃java〃;□//構造器,可對既沒有指定默認值,又沒有在初始化塊中指定初始值的實例變量指定初始值TOC\o"1-5"\h\zC=5;4}publicvoidchangeFinal(){a//普通方法不能為final修飾的成員變量賦值匚//d=1.2;//不能在普通方法中為fina1成員變量指定初始值//ch=a7;□}pub1icstaticvoidmain(String[]args){aFinalVariableTestft=newFinalVariableTest();aSystem.out.print1n(ft.a);System.out.print1n(ft.c);aSystem,out.printIn(ft.d)}a}Final局部變量系統(tǒng)不會對局部變量進行初始化,局部變量必須由程序員顯式初始化。因此final修飾局部變量時,既可以在定義時指定默認值,也可以不指定默認值。假如final修飾的局部變量在定義時沒有指定默認值,則可以在后面代碼中對該final變量賦初始值,但只能一次,不能反復賦值。當使用final修飾基本類型變量時,不能對基本類型變量重新賦值,因此基本列表變量不能改變。但對于引用類型變量而言,它保存的僅僅是一個引用,final只保證這個引用類型變量所引用的地址不會改變,即一直引用同一個對象,但這個對象完全可以改變。pub1icc1assFinalReferenceTest{publicstaticvoidmain(String[]args){//fina1修飾數(shù)組變量,1Arr是一個引用變量fina1int[]iArr={5,6,12,9);aSystem.out.print1n(Arrays.toString(iArr));〃對數(shù)組元素排序,合法Arrays.sort{iArr)”System.out.printin(Arrays.toStrin1Arr));a//對數(shù)組元素賦值,合法QiArr[2]=-8;aSystem.out.println(Arrays,toString{iArr));a//對iArr重新賦值,非法//iArr=nu11;//final修飾Person變量,p是一個引用變量。finalPersonp=newPerson(45);//改變P對象的age實例變量,分決:p.setAge(23);System.out.printin(p.getAge());//對P重新賦值,非法成員變量:a成員變量的修飾符:public、protected、private、static>fina1前三個只能出現(xiàn)一個再和后面的修飾符組合起來修飾成員變量,也可省略。成員變量:由一個或者多個故意義的單詞連綴而成,第一個單詞首字母小寫,后面每個單詞首字母大寫,其他字母所有小寫,單詞與單詞之間不要使用任何分隔符。類型:可以是java語言允許的任何數(shù)據(jù)類型,涉及基本類型和引用類型。成員方法:方法修飾符:pub1ic、protected、private、static、fina1>abstract,前三個只能出現(xiàn)~*個,static和final最多只能出現(xiàn)其中的一個,和abstract組合起來使用。也可省略。a返回值類型:可以是java語言的允許的任何數(shù)據(jù)類型,涉及基本類型和引用類型。a方法名:和成員變量的方法命名規(guī)則相同,通常建議方法名以英文動詞開頭。方法體里多條可執(zhí)行語句之間有嚴格的執(zhí)行順序,排在方法體前面的語句總先執(zhí)行,排在方法體后面的語句總是后執(zhí)行。astatic是一個特殊的關鍵字,它可用于修飾方法、成員變量等成員。static修飾的成員表白它屬于這個類自身,而不屬于該類的單個實例,因此通過把static修飾的成員變量和方法被稱為類變量、類方法(靜態(tài)成員變量,靜態(tài)成員方法);不使用static修飾的成員變量和方法稱為實例變量和實例方法(非靜態(tài)成員變量,非靜態(tài)成員方法)。靜態(tài)成員不能直接訪問非靜態(tài)成員。astatic的真正作用就是用于區(qū)提成員變量、方法、內(nèi)部類、初始化塊,這四種成員到底屬于類自身還是屬于實例。有static修飾的成員屬于類自身,沒有類修飾的成員屬于該類的實例。java類大體有如下作用:定義變量地I建對象a調(diào)用類的類方法或訪問類的類變量。定義一個類就是為了反復創(chuàng)建該類的實例,同一個類的多個實例具有相同的特性,而類則是定義了多個實例的共同特性。類里定義的方法和成員變量都可以通過類或實例來調(diào)用。Static修飾的方法和成員變量,既可通過類來調(diào)用,也可通過實例來調(diào)用;沒有使用static修飾的普通方法成員變量,只可通過實例來調(diào)用。Personp=newPerson();這行代碼創(chuàng)建了一個Person實例,也被稱為Person對象,這個Person對象被賦給P變量。在這行代碼中事實上產(chǎn)生了兩個東西,一個是P變量,一個是Person對象。P引用變量自身只存//P=null;a}}classPerson{privateintage;publicPerson(){)//有參數(shù)的構造器1pub1icPerson(intage){this,age=age;a}apublicvoidsetAge(int.age){athis,age=age;)pub1icintgetAge(){returnage;}◎}可執(zhí)行“宏替換”的final變量對于一個final變量來說,不管它是類變量、實例變量,還是局部變量,只要該變量滿足三個條件,這個final變量就不再是一個變量,而是相稱于一個直接量1)使用final修飾符修飾2)在定義該final變量時指定了初始值3)該初始值可以在編譯時就被擬定下來假如被賦的表達式只是基本的算術表達式或字符串連接運算,沒有訪問普通變量,調(diào)用方法,java編譯器同樣會將這種final變量當成“宏變量”解決。pub1icclassFinalReplaceTest{publicstaticvoidmain(String[]args)區(qū)〃下面定義了4個final宏變量,由于編譯器在編譯時就可以擬定finalint”5+2;fina1doub1eb=1.2/3;finalStringstr="瘋狂"java";afinalStringbook="瘋狂java講義:"+99.0;//下面的b。ok2變量的值由于調(diào)用了方法,所以無法在編譯時被擬定下來〕finalStringbook2=n瘋狂java講義:"+String.va1ue(9/(99.0);System,out.printin(book=="瘋狂Java講義:99.0");//相等'System.out.printin(book2二二”瘋狂java講義:99.0H);〃不相等二}Java會使用常量池來管理曾經(jīng)用過的字符串直接量,例如執(zhí)行Stringajava”,語句之后,常量池中就會緩存一個字符串“Java";假如程序再執(zhí)行Stringb="java”,系統(tǒng)將會讓b直接指向常量池中的“java”字符串,因此a==b將會返回true.publicclassStringJoinTest{publiestaticvoidmain(String[]args){Stringsi="瘋狂java";〃s2變量引用的字符串可以在編譯時就擬定下來,因此s2的直接引用常量池中已有的“瘋狂java〃字符串二Strings2=”瘋狂"+"java";System.out.println(s1==s2);Stringstr1二"瘋狂";aStringstr2="java";a//str31tlstr1和str2進行連接運算后得到的。由于strl和str2只是兩個普通變量,編譯器不會執(zhí)行“宏替換”,因而不能入〃編譯時擬定s3的值,也就無法讓s3指定字符串池中緩存的“瘋狂Ja儂"口Strings3=strl+str2;^System.out.print1n(sl==s3);a//只要讓編譯器對strl和str2兩個變量執(zhí)行“宏替換:這樣編譯器即可在編譯階段就擬定s3的值,就會讓S3指向字符串池//中緩存的“瘋狂java”。也就是,只要將str1和str2使用final修飾即可Fina1方法Final修飾的方法不可被重寫,但是可以重載Fina1類Fina1修飾的類不可以有子類。因而為了保證某個類不可被繼承,則可以使用final修飾這個類。5.5抽象類抽象方法和抽象類必須使用abstract修飾符來定義,有抽象方法的類只能被定義成抽象類,抽象類里可以沒有抽象方法。抽象方法和抽象類的規(guī)則如下:1)抽象類必須使用abstract修飾符來修飾,抽象方法也必須使用abstract修飾符來修飾,抽象方法不能有方法體。2)抽象類不能被實例化,無法使用new關鍵字來調(diào)用抽象類的構造器創(chuàng)建抽象類的實例。即使抽象類里不包含抽象方法,這個抽象類也不能創(chuàng)建實例。3)抽象類可以包含成員變量、方法(普通方法和抽象方法都可以)、構造器、初始化塊、內(nèi)部類(接口、枚舉)5種成分。抽象類的構造器不能用于創(chuàng)建實例,重要是用于被其他子類調(diào)用。4)具有抽象方法的類(涉及直接定義了一個抽象方法;或繼承了一個抽象父類,但沒有完全實現(xiàn)父類包含的抽象方法;或實現(xiàn)了一個接口,但沒有完全實現(xiàn)接口包含的抽象方法三種情況)只能被定義成抽象類。抽象類:多了一個能力,抽象類可以包含抽象方法;失去了一個能力,抽象類不能用于創(chuàng)建實例。定義抽象方法只需在普通方法上增長abstract修飾符,并把普通方法的方法體(也就是方法后花括號括起來的部分)所有去掉,并在方法后增長分號即可。定義抽象類只需在普通類上增長abstract修飾符即可。/**CreatedbyAIwenon2023/5/19.*/publicabstractc1ass.Shape{{_System.out.printin("執(zhí)行shape的初始化塊???")闖aprivateStringco1or;a//定義一個計嵬周長的抽象方法〕Publicabstractdoub1ecalPerimeter();a//定義一個返回形狀的抽象方法publicabstractStringgetType();//定義Shape的構造器,該構造器并不是用于創(chuàng)建Shape對象,而是用于被子類調(diào)用口publicShape(){}publieShape(Stringcolor){System.out.println("執(zhí)行Shape構造器”);athis.color=color;A}apublicvoidsetColor(Stringcolor){this,color=co1or;}apublieStringgetColor(){areturnco1or;}}publieclassTriangleextendsShapeprivatedoublea;Aprivatedoubleb;privatedoub1ec;^publicTriang1e(Stringcolor,doub1ea,doub1eb,doublec){asuper(color);athis,setSides(a,b,c);)publicvoidsetSides(doublea,doubleb,doublec){aif(a>=b+c||b>=a+c|Ic>=a+b){aSystem.out.printin("三角形兩邊之和必須大于第三邊");return;}this.a=a;athis.b=b;this.c=c;}apublicdoublecalPerimeter(){returna+b+c;}publicStringgetTypeO{areturn”三角形n;))publicc1assCircleextendsShape{aprivatedoubleradius-publicCircle(Stringcolor,doubleradius){super(co1or);athis.radius=radius;a}publicvoidsetRadius(doubleradius){△this,radius=radius;a}apublicdoublecalPerimeter(){areturn2*Math./V*radius;a}apublicStringgetType。{areturngetColor()+“圓形";4)publicstaticvoidmain(String[]args){Shapes1=newTriangle(“黑色",3,4,5);Shapes2=newCircle(n黃色“,3);aSystem.out.println(sl.getType());System.out.printin(si.calPerimeter()),冷System.out.printin(s2.getType());aSystem,out.print1n(s2.calPerimeter())}△}當使用abstract修飾類時,表白這個類只能被繼承;當使用abstract修飾方法時,表白這個方法必須由子類提供實現(xiàn)(即重寫)。而final修飾的類不能被繼承,final修飾的方法不能被重寫。因此final和abstract永遠不能同時使用。Abstract不能修飾變量,也不能用于修飾構造器。Static和abstract不能同時修飾某個方法,但它們可以同時修飾內(nèi)部類。Private和abstract不能同時修飾方法抽象類不能創(chuàng)建實例,只能當成父類來被繼承。抽象類體現(xiàn)的就是一種模板模式的設計。假如編寫一個抽象父類,父類提供了多個子類的通用方法,并把一個或多個方法留給其子類實現(xiàn),這就是一種模板模式,模板模式也是十分常見且簡樸的設計模式之一。publicabstractclassSpeedMeter{aprivatedoubleturnRate;apublieSpeedMeter(),卜//把返回車輪半徑的方法定義成抽象方法publicabstractdoublegetRadius();apublicvoidsetTurnRate(doubleturnRate){athis,turnRate=turnRate;)publiedoublegetSpeed(){areturnjava.Iang.Math.PI^2etRadius()*turnRate;a}}pub1icclassCarSpeedMeterextendsSpeedMeterpublicdoublegetRadius(){areturn0.28;)publiestaticvoidmain(String[]args){CarSpeedMetercsm=newCarSpeedMeter();acsm.setTurnRate(15);aSystem,out.println(csm.getSpeed());5.6java8改善的接口接口里不能包含普通方法,接口里的所有方法都是抽象方法。Java8對接口進行了改善,允許在接口中定義默認方法,默認方法可以提供方法實現(xiàn)。接口定義了某一批類所需要遵守的規(guī)范,接口不關心這些類的內(nèi)部狀態(tài)數(shù)據(jù),也不關心這些類里方法的實現(xiàn)細節(jié),它只規(guī)定這批類里必須提供某些方法,提供這些方法的類就可滿足實際需要。接口是從多個相似類中抽象出來的規(guī)范,接口不提供任何實現(xiàn)。定義接口使用interface關鍵字1)修飾符可以是PUblie或者省略,假如省略了publie訪問控制符,則默認采用包訪問控制符,即只有在相同包結構下才可以訪問該接口。2)接口名應與類名采用相同的命名規(guī)則,接口名通??梢允褂眯稳菰~。3)一個接口可以有多個直接父接口,但接口只能繼承接口,不能繼承類。由于接口定義的是一種規(guī)范,因此接口里不能包含構造器和初始化塊定義。接口里可以包含成員變量(只能是靜態(tài)常量)、方法(只能是抽象實例方法、類方法或默認方法)、內(nèi)部類(涉及內(nèi)部接口、枚舉)定義。接口里定義的是多個類共同的公共行為規(guī)范,因此接口里的所有成員,涉及常量、方法、內(nèi)部類和內(nèi)部枚舉都是public訪問權限。定義接口成員時,可以省略訪問控制修飾符,假如指定訪問控制修飾符,則只能使用public訪問控制修飾符。對于接口里的定義的靜態(tài)常量而言,它們是接口相關的,因此系統(tǒng)會自動為這些成員變量增長static和final兩個修飾符。也就是說,在接口中定義成員變量時,不管是否使用pub1icstaticfinal修飾符,接口里的成員變量總是使用這三個修飾符來修飾。并且接口里沒有構造器和初始化塊,因此接口里定義的成員變量只能在定義時指定默認值。接口里定義的方法只能是抽象方法、類方法或默認方法,因此假如不是定義默認方法,系統(tǒng)將自動為普通方法增長abstract修飾符;定義接口里的普通方法時不管是否使用publieabstract修飾符,接口里的普通方法總是使用pub1icabstract來修飾。接口里的普通方法不能有方法實現(xiàn)(方法體);但類方法、默認方法都必須由方法實現(xiàn)(方法體).接口里定義的內(nèi)部類、內(nèi)部接口、內(nèi)部枚舉默認都采用publiestatic兩個修飾符publicinterface0utput{a//接口里定義的成員變量只能是常量jintMAX_CACHE_L77^50;//接口里定義的普通方法只能是public的抽象方法「voidout();avoidgetData(Stringmsg);//接口中定義的默認方法,需要使用defuaIt修紡]defauItvoidprint(String...msgs),for(Stringmsg:msgs){aSystem.out.printin(msg);))defaultvoidtest(){System.out.print1n(〃默認的test()方法”);八//在接口中定義類方法,需要使用static修飾staticStringstatic?est(){return”接口中的類方法”;△}聞Java8允許在接口中定義默認方法,默認方法必須使用default修飾,該方法不能使用static修飾,無論程序是否指定,默認方法總是使用Public修飾。由于默認方法不能使用static修飾,因此不能直接使用接口來調(diào)用默認方法,需要使用接口的實現(xiàn)類的實例來調(diào)用這些默認方法Java8允許在接口中定義類方法,類方法必須使用static修飾,該方法不能使用default修飾。無論程序是否指定,類方法總是使用publ1C修飾。類方法可以直接使用接口來調(diào)用。接口中的成員變量默認是使用publicstaticfinal修飾,因此即使另一個類處在不同包下,也可以通過接口來訪問接口里的成員變量。從某個角度來看,接口可被當成一個特殊的類,因此一個java源文獻里最多只能有一個Publie接口,假如一個java源文獻里定義了一個public接口,則該源文獻的主文獻名必須與該接口名相同。接口的繼承:接口的繼承和類繼承不同樣,接口完全支持多繼承,即一個接口可以有多個直接父接口。和類繼承相似,子接口擴展某個父接口,將會獲得父接口里定義的所有抽象方法、常量。一個接口繼承多個父接口,多個父接口排在extends關鍵字之后,多個父接口之間以英文逗號隔開。publicclassInterfaceExtendsTest{apublicstaticvoidmain(String]]args){aSystem.out.println(interfaceC.PROP_A);System.out.printin(interfaceC.PROP_B);aSystem.out.printin(interfaceC.PROPC);a}A)AinterfaceinterfaceA{intPR0P_A^3;avoidtestA();)interfaceinterfaceBbintPR0P_B^6;4voidtestB();}ainterfaceinterfaceCextendsinterfaceA,interfaceB{aint.PROP合7voidtestC();一個類可以實現(xiàn)一個或者多個接口,繼承使用extends關鍵字,實現(xiàn)則使用implements關鍵字。一個類可以繼承一個父類,并同時實現(xiàn)多個接口,implements部分必須放在extends部分之后。一個類實現(xiàn)類一個或多個接口之后,這個類必須完全實現(xiàn)這些接口里所定義的所有抽象方法(也就是重寫這些抽象方法);否則,該類將保存從父接口那里繼承到的抽象方法,該類也必須定義成抽象類。接口和抽象類相同點:接口和抽象類都不能實例化,都包含抽象方法。不同點:1)接口里只能包含抽象方法和默認方法,不能為普通方法提供方法實現(xiàn);抽象類則完全可以包含普通方法2)接口里不能定義靜態(tài)方法;抽象類里可以定義靜態(tài)方法3)接口里只能定義靜態(tài)常量,不能定義普通成員變量;抽象類里既可以定義普通成員變量,也可以定義靜態(tài)常量4)接口里不包含構造器;抽象類里可以包含構造器,抽象類里的構造器并不是用于創(chuàng)建對象,而是讓其子類調(diào)用這些構造器來完畢屬于抽象類的初始化操作。5)接口里不能包含初始化塊;但抽象類則完全可以包含初始化塊。6)一個類最多只能有一個直接父類,涉及抽象類;但一個類可以直接實現(xiàn)多個接口,通過實現(xiàn)多個接口可以填補java單繼承的局限性。5.7內(nèi)部類1)內(nèi)部類提供了更好的封裝,把內(nèi)部類隱藏在外部類之內(nèi),不允許同一個包中的其他類訪問該類。2)內(nèi)部類成員可以直接訪問外部類的私有數(shù)據(jù),由于內(nèi)部類被當成其他外部類成員,同一個類的成員之間可以互相訪問。但外部類不能訪問內(nèi)部類的實現(xiàn)細節(jié),例如內(nèi)部類的成員變量。3)匿名內(nèi)部類適合用于創(chuàng)建那些僅需要一次使用的類。內(nèi)部類除了需要定義在其他類里面之外,還存在如下兩點:1)內(nèi)部類比外部類可以多使用三個修飾符:private、protected、static—外部類不可以使用這三個修飾符。2)非靜態(tài)內(nèi)部類不能擁有靜態(tài)成員在非靜態(tài)內(nèi)部類中可以直接訪問外部類的Private的實例變量:publicclassCow{aprivatedoubleweight;publicCow(){}apub1icCow(doubleweigth){athis,weight=weight}privatec1assCowLeg{a//非靜態(tài)內(nèi)部類的兩個實例變量〕privatedoublelength;private.Stringcolor;PublicCowLegO{}a//非靜態(tài)內(nèi)部類的兩個重載的構造器pub1icCowLeg(doub1elength,Stringcolor){this.length=length;TOC\o"1-5"\h\zthis.color=co1or;A}publicvoidsetLength(doub1e1ength){this,length=length;a}pub1icdoublegetLengthOOreturn1ength;a}publicvoidsetColor(Stringcolor){this,color=color;a}apublicStringgetClor(){returnco1or;)//非靜態(tài)內(nèi)部類的實例方志Publicvoidinfo(){aSystem,out,print1n("當前牛的顏色:"+co1or+〃高:+length);//直接訪問外部類的private修飾的成員變量-System.□wtprintln(“本牛腿所在奶牛重:"+weight);)}apublicvoidtest(){CowLegcl=newCowLeg(l.12,”黑白相間〃);();}apublicstaticvoidmain(String[]args){aCowcow=newCow(378.9);cow.test();岡假如外部類成員變量、內(nèi)部類成員與內(nèi)部類里方法的局部變量同名,則可通過使用this、外部類類名.this作為限定來區(qū)分:pub1icc1assDiscernVariable{△privateStringprop=”外部類的實例變量”;privateclassInClass{PrivateStringprop="內(nèi)部類的實例變量";publievoidinfo(){aStringprop=“局部變量”;//System.out.println("外部類的實例變量:〃+newDiscemVp);//通過外部類類名.this.varName訪問

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論