java基础学习笔记(二)
?
1、數(shù)組排序之選擇法排序和冒泡排序?
選擇法排序原理:數(shù)組第一位和后續(xù)位置數(shù)值比較,最大或最小的調(diào)換位置后放在第一位;依次比較將第二大或小的值調(diào)換位置后放在第二位置;代碼如下:
for (int j = 0; j < a.length-1; j++) {for (int i = j+1; i < a.length; i++) {if(a[i]<a[j]){ int temp = a[j];a[j] = a[i];a[i] = temp;}}}冒泡法排序原理:數(shù)組相鄰兩個(gè)arr[i] 和arr[i+1]進(jìn)行比較后將最大或最小的放在最后,循環(huán)比較后,最后一位是最大或最小的數(shù)值。代碼如下
for (int j = 0; j < a.length; j++) {for (int i = 0; i < a.length-j-1; i++) {if(a[i]>a[i+1]){ int temp = a[i+1];a[i+1] = a[i];a[i] = temp;}}}?
2、二維數(shù)組的分配空間及賦值:?int[][] b=new int[2][3];表示該二維數(shù)組是有兩個(gè)長(zhǎng)度為3的一維數(shù)組組成,未初始化;int[][] b=new int[][]{ {1,2,3},{2,3,4} }
?
3、數(shù)組操作:Arrays是針對(duì)數(shù)組的工具類,可以進(jìn)行 排序,查找,復(fù)制填充等功能。 大大提高了開發(fā)人員的工作效率。
數(shù)組復(fù)制方法:使用system.arrayCopy 方法,如System.arraycopy(src, srcPos, dest, destPos, length)將源數(shù)組數(shù)據(jù)復(fù)制到目標(biāo)數(shù)組;使用Arrays.copyOfRange((src, srcPos, dest, destPos, )的返回值就是復(fù)制獲取的數(shù)組;具體數(shù)組方法操作見 http://how2j.cn/k/array/array-arrays/516.html
?
4、引用:聲明一個(gè)非基本類型的變量后,那么這個(gè)變量叫做引用。如使用new Hero()創(chuàng)建一個(gè)對(duì)象后怎么訪問(wèn)這個(gè)對(duì)象,就需要通過(guò)“=”等于號(hào)將引用指向該對(duì)象,如Hero h1=new Hero(); 引用前的Hero表示這個(gè)變量h1是Hero類型的。
?
5、多個(gè)引用可以指向的是一個(gè)對(duì)象,一個(gè)引用同時(shí)只能指向一個(gè)對(duì)象如 Hero garen=new Hero(); 和garen=new Hero(); 會(huì)沖突。注意:每次實(shí)例化一個(gè)對(duì)象時(shí),系統(tǒng)會(huì)分配一塊內(nèi)存地址給這個(gè)對(duì)象,而系統(tǒng)默認(rèn)是根據(jù)內(nèi)存地址來(lái)檢測(cè)是否是同一個(gè)對(duì)象,所以就算是同一個(gè)類里實(shí)例化出來(lái)的對(duì)象它們也不會(huì)相等。如:
Hero h1=new Hero();Hero h2=new Hero();System.out.println(h1.equals(h2)); //false,因?yàn)閷?shí)例化的對(duì)象分配在不同的內(nèi)存地址?
6、Java類使用extend關(guān)鍵詞實(shí)現(xiàn)繼承類。方法的重載指的是方法名一樣,但是參數(shù)類型不一樣。重載方法過(guò)多時(shí)可以使用可變數(shù)量的參數(shù),如public void attack(Hero?...heros),在方法里,使用操作數(shù)組的方式處理參數(shù)heros即可。
public class ADHero extends Hero {public void attack() {System.out.println(name + " 進(jìn)行了一次攻擊 ,但是不確定打中誰(shuí)了");}public void attack(Hero h1) {System.out.println(name + "對(duì)" + h1.name + "進(jìn)行了一次攻擊 ");}public void attack(Hero h1, Hero h2) {System.out.println(name + "同時(shí)對(duì)" + h1.name + "和" + h2.name + "進(jìn)行了攻擊 ");}public static void main(String[] args) {ADHero bh = new ADHero();bh.name = "賞金獵人";Hero h1 = new Hero();h1.name = "蓋倫";Hero h2 = new Hero();h2.name = "提莫";bh.attack(h1);bh.attack(h1, h2);}}?
7、構(gòu)造方法理解:通過(guò)一個(gè)類創(chuàng)建一個(gè)對(duì)象的過(guò)程叫做實(shí)例化,實(shí)例化是通過(guò)構(gòu)造方法實(shí)踐的。什么是構(gòu)造方法?構(gòu)造方法名和類名一致,但沒有返回類型,實(shí)例化一個(gè)對(duì)象時(shí)必調(diào)用構(gòu)造方法。如下
public class Hero extends Person {public Hero() { //無(wú)返回類型System.out.println("這是Hero類的構(gòu)造方法");}public static void main(String[] args) {int[] a= {11,22,321,32,355};Hero h1=new Hero(); //實(shí)例化對(duì)象會(huì)調(diào)用后構(gòu)造方法} }注意:類的構(gòu)造方法不寫的話,會(huì)默認(rèn)提供一個(gè)無(wú)參構(gòu)造方法。一旦提供了有參的構(gòu)造方法,那么默認(rèn)的無(wú)參的構(gòu)造方法就沒有了;和普通的構(gòu)造方法一樣,構(gòu)造方法也可以重載。
?
8、java中this和this(),?在java中this指當(dāng)前對(duì)象。在一個(gè)構(gòu)造方法中調(diào)用另一個(gè)構(gòu)造方法可以使用this(); 如下
public Hero(String name) { //無(wú)返回類型System.out.println("這是Hero類的構(gòu)造方法,名字是:"+name);} public Hero(String name,int age) { //無(wú)返回類型this(name); //構(gòu)造方法中可以使用this調(diào)用另一個(gè)構(gòu)造方法System.out.println("年齡是:"+age);}?
9、變量包括基本類型和類類型,參數(shù)也是變量,所以傳參分為基本類型傳參和類類型傳參。總結(jié)來(lái)說(shuō)變量是基本類型則叫變量,如int a=12;a是變量,通過(guò)等號(hào)進(jìn)行賦值;如果變量不是基本類型而是類類型,如Hero h1=new Hero(); h1是類類型的,叫引用,通過(guò)等號(hào)指向?qū)嵗龑?duì)象;
?
10、Package把相近的類劃在一個(gè)包下,使用同包類的其他類直接使用就可以,使用不同包下的類則需要使用import引入。
?
11、類與類之間的關(guān)系:
成員變量有四種修飾符
private?私有的
package/friendly/default 不寫
protected?受保護(hù)的
public?公共的
以Hero為例
自身:指的是Hero自己
同包子類:ADHero這個(gè)類是Hero的子類,并且和Hero處于同一個(gè)包下
不同包子類:Support這個(gè)類是Hero的子類,但是在另一個(gè)包下
同包類:?GiantDragon 這個(gè)類和Hero是同一個(gè)包,但是彼此沒有繼承關(guān)系
其他類:Item這個(gè)類,在不同包,也沒有繼承關(guān)系的類
概括就是private修飾的成員變量只能被本身類所訪問(wèn),default修飾(默認(rèn))的成員變量只能被自身和同包的類訪問(wèn),protected修飾的成員變量可以被自身或同包類或子類訪問(wèn),public修飾的變量可以被任何類訪問(wèn)。
使用技巧:屬性通常使用private封裝起來(lái);方法一般使用public便于調(diào)用;會(huì)被子類繼承的的方法,通常使用protected;作用范圍最小原則就是能用private就用private,不行就網(wǎng)上default》protected》public
參考網(wǎng)址:http://how2j.cn/k/class-object/class-object-modifier/295.html#nowhere
?
12、單例模式:又叫做 Singleton模式,指的是一個(gè)類,在一個(gè)JVM里,只有一個(gè)實(shí)例存在。
餓漢式單例模式原理是通過(guò)私有化構(gòu)造函數(shù)使外部無(wú)法實(shí)例化對(duì)象,再通過(guò)在類內(nèi)部實(shí)例化一個(gè)該對(duì)象賦值給類屬性(靜態(tài)屬性在內(nèi)存上使唯一的),在通過(guò)提供靜態(tài)方法來(lái)訪問(wèn)該靜態(tài)屬性,代碼示例如下:
public class GiantDragon { //私有化構(gòu)造方法使得該類無(wú)法在外部通過(guò)new 進(jìn)行實(shí)例化private GiantDragon(){} //準(zhǔn)備一個(gè)類屬性,指向一個(gè)實(shí)例化對(duì)象。 因?yàn)槭穷悓傩?#xff0c;所以只有一個(gè) private static GiantDragon instance = new GiantDragon(); //public static 方法,提供給調(diào)用者獲取12行定義的對(duì)象public static GiantDragon getInstance(){return instance;} }懶漢式單例模式的不同是只有在getInstance的時(shí)候才會(huì)創(chuàng)建示例,如下:
//準(zhǔn)備一個(gè)類屬性,用于指向一個(gè)實(shí)例化對(duì)象,但是暫時(shí)指向nullprivate static GiantDragon instance;//public static 方法,返回實(shí)例對(duì)象public static GiantDragon getInstance(){//第一次訪問(wèn)的時(shí)候,發(fā)現(xiàn)instance沒有指向任何對(duì)象,這時(shí)實(shí)例化一個(gè)對(duì)象if(null==instance){instance = new GiantDragon();}//返回 instance指向的對(duì)象return instance;} public static void main(String[] args) {//通過(guò)new實(shí)例化會(huì)報(bào)錯(cuò)// GiantDragon g = new GiantDragon(); //只能通過(guò)getInstance得到對(duì)象 GiantDragon g1 = GiantDragon.getInstance();GiantDragon g2 = GiantDragon.getInstance();GiantDragon g3 = GiantDragon.getInstance(); //都是同一個(gè)對(duì)象System.out.println(g1==g2);System.out.println(g1==g3);}區(qū)別、使用技巧(什么時(shí)候使用餓漢式單例模式,什么時(shí)候使用懶漢式單例模式?)
餓漢式是立即加載的,無(wú)論是否使用到這個(gè)對(duì)象都會(huì)加載,如果構(gòu)造函數(shù)中寫了性能消耗較大、占時(shí)較長(zhǎng)的代碼,比如建立和數(shù)據(jù)的連接,那么就會(huì)在啟動(dòng)的時(shí)候稍微有些卡頓;懶漢式是延遲加載的方式,只有在使用的時(shí)候才會(huì)加載,并且有線程安全的考量。使用懶漢式,在啟動(dòng)的時(shí)候,會(huì)感覺到比餓漢式略快,因?yàn)椴]有做對(duì)象的實(shí)例化。 但是在第一次調(diào)用的時(shí)候,會(huì)進(jìn)行實(shí)例化操作,感覺上就略慢。看業(yè)務(wù)需求,如果業(yè)務(wù)上允許有比較充分的啟動(dòng)和初始化時(shí)間,就使用餓漢式,否則就使用懶漢式
?
13、對(duì)象轉(zhuǎn)型,類型轉(zhuǎn)換指的是改變引用所指向的對(duì)象類型。通常Hero h=new Hero(); 中h引用的引用類型是Hero,new Hero()創(chuàng)建的對(duì)象是Hero對(duì)象,引用類型和對(duì)象類型是一樣的。 那么引用類型和對(duì)象類型不一樣的情況下會(huì)怎么樣?向上轉(zhuǎn)型(子類可以轉(zhuǎn)父類),如Hero h = new Hero();ADHero ad = new ADHero(); h = ad; ?這里h引用重新指向了ADHero對(duì)象類型。判斷類型轉(zhuǎn)換能否成功,可以嘗試將右邊的當(dāng)做左邊的來(lái)用看是否行的通,如ADhero當(dāng)hero英雄是可以的,強(qiáng)制轉(zhuǎn)換如ad=(ADhero)h;
注意:沒有繼承關(guān)系的類進(jìn)行轉(zhuǎn)換是不可以的,拋出異常 ClassCastException 類型轉(zhuǎn)換異常。如ad = (ADHero) ap;會(huì)失敗。?實(shí)現(xiàn)類轉(zhuǎn)換成接口是可以的,如AD adi=new ADhero();因?yàn)閷?shí)現(xiàn)類ADhero對(duì)象是完全實(shí)現(xiàn)了接口中的方法的,所以當(dāng)接口用是可以的。
h1 instanceof Hero 可以判斷h1引用指向的對(duì)象類型是否為Hero,個(gè)人理解是:類型轉(zhuǎn)換改變的引用的指向,并沒有改變引用類型。
package charactor;public class TestHero extends Hero {public static void main(String[] args) {Hero h=new Hero();TestHero th=new TestHero();h=th; //類型轉(zhuǎn)換:h引用重新指向子類對(duì)象TestHero,所以使用h引用調(diào)用的方法,調(diào)用的是TestHero對(duì)象的方法h.test(); //輸出 TestHero類的方法th.test(); //輸出 TestHero類的方法System.out.println(h instanceof TestHero ); //instanceof判斷左側(cè)是否是右側(cè)的實(shí)例對(duì)象System.out.println(h instanceof Hero ); //true,因?yàn)橐弥赶虻膶?duì)象繼承了Hero對(duì)象}public void test() {System.out.println("TestHero類的方法");}}14、繼承重寫:子類可以繼承父類的對(duì)象方法,在繼承后重復(fù)提供該方法,就叫做方法的重寫或override
另外重載發(fā)生在同一個(gè)類(如構(gòu)造方法帶參和不帶參),重寫發(fā)生在不同類(如多態(tài)的實(shí)現(xiàn))。
?
15、多態(tài):操作符的多態(tài)體現(xiàn)在“+”加號(hào)上,加號(hào)兩側(cè)是整形則兩側(cè)數(shù)字相加,如果加號(hào)兩側(cè)任意一個(gè)是字符串則加號(hào)代表字符串連接。多態(tài)是指同一個(gè)類型調(diào)用同一個(gè)方法,卻能呈現(xiàn)不同的狀態(tài)。可以理解類型轉(zhuǎn)換和繼承重寫結(jié)合后形成多態(tài)代。碼如下:
Item i1= new LifePotion(); //這里引用類型都是父類類型,指向到不同的子類實(shí)例上,所以輸出不一樣Item i2 = new MagicPotion();System.out.print("i1 是Item類型,執(zhí)行effect打印:");i1.effect();System.out.print("i2也是Item類型,執(zhí)行effect打印:");i2.effect();多態(tài)形成的條件是:父類(接口)引用指向子類對(duì)象,調(diào)用的方法有重寫。
參考網(wǎng)址:http://how2j.cn/k/interface-inheritance/interface-inheritance-polymorphic/315.html
?
?16、隱藏:方法的重寫是子類覆蓋父類的對(duì)象方法。隱藏就是子類對(duì)父類的類方法(靜態(tài)方法)的重寫。Hero h =new ADHero();?h.battleWin(); 在battleWin()方法是類方法時(shí),注意父類的引用無(wú)論指向哪個(gè)對(duì)象都執(zhí)行的類方法仍然是父類的類方法。。
package charactor;public class Hero {public static void test() {System.out.println("Hero類的靜態(tài)方法");} }?
package charactor;public class TestHero extends Hero {public static void main(String[] args) {// TODO Auto-generated method stubTestHero.test(); //繼承父類后對(duì)父類的靜態(tài)方法的重寫叫做隱藏Hero.test();Hero th=new TestHero(); //父類類型的引用指向子類對(duì)象,會(huì)對(duì)象轉(zhuǎn)型為父類Hero類型th.test(); //但是調(diào)用的還是引用類型父類的靜態(tài)方法!!}public static void test() {System.out.println("繼承Hero類的后對(duì)test靜態(tài)方法進(jìn)行覆蓋叫做隱藏");}}?
17、實(shí)例化子類,父類的構(gòu)造方法一定會(huì)被調(diào)用,而且父類的構(gòu)造方法會(huì)被優(yōu)先調(diào)用。如果實(shí)例化子類時(shí)帶參數(shù),就需要用到super(參數(shù))來(lái)調(diào)用父類的有參構(gòu)造方法,如下:
public Hero(String name) { //無(wú)參顯示構(gòu)造方法 System.out.println("Hero類的有參構(gòu)造方法"); this.name=name; } public APhero(String name) {super(name); //注意位置必須在構(gòu)造方法的第一行System.out.println("APhero類的有參構(gòu)造方法,需要使用super關(guān)鍵字");}public static void main(String[] args) {APhero ap1=new APhero("teemo");}Super關(guān)鍵字:還可以使用通過(guò)super調(diào)用父類的屬性,如this.moveSpeed 和super.moveSpeed。
?
18、Object類是所有類的父類,聲明一個(gè)類的時(shí)候默認(rèn)是繼承了Object類的,
- Object類有toString()方法返回當(dāng)前對(duì)象的字符串表達(dá);
- finalize()方法是當(dāng)一個(gè)對(duì)象沒有任何指向的時(shí)候就會(huì)觸發(fā)垃圾回收機(jī)制,垃圾回收時(shí)JVM會(huì)調(diào)用該方法。
- equals()方法判斷兩個(gè)對(duì)象內(nèi)容是否一致。“==”不是Object的方法,但是可以判斷兩個(gè)引用是否指向一個(gè)對(duì)象。
- hashCode() 方法返回一個(gè)對(duì)象的哈希值。
- Object還提供線程同步相關(guān)方法wait()、notify()、notifyAll()。getClass()會(huì)返回一個(gè)對(duì)象的類對(duì)象,屬于高級(jí)內(nèi)容。
?
19、抽象類:在類中聲明一個(gè)方法,該方法沒有實(shí)現(xiàn)主體,是一個(gè)“空”方法,這個(gè)方法就叫做抽象方法,使用“abstract”修飾,當(dāng)一個(gè)類中有抽象方法時(shí),這個(gè)類就叫做抽象類。子類可以通過(guò)繼承抽象類實(shí)現(xiàn)不同的方法。抽象類可以不包含抽象方法,但是抽象類不能被實(shí)例化。
抽象類和接口都定義了不包含方法體的方法,那么有什么其他的區(qū)別?區(qū)別一:子類只能繼承一個(gè)抽象類但可以實(shí)現(xiàn)多個(gè)接口。區(qū)別二:接口中聲明的屬性只能是public static final的,而抽象類中可以定義public、defalut、protected、private類型的、靜態(tài)和非靜態(tài)屬性、final和非final的屬性。
?
20、內(nèi)部類:包括非靜態(tài)內(nèi)部類和靜態(tài)內(nèi)部類、匿名類、本地類。語(yǔ)法:?new 外部類().new 內(nèi)部類()。所以非靜態(tài)內(nèi)部類的實(shí)例必須建立在一個(gè)外部類對(duì)象的基礎(chǔ)上的。
?
21、匿名類是指在聲明一個(gè)類的同時(shí)實(shí)例化它,通常要使用一個(gè)接口或一個(gè)抽象類必須創(chuàng)建一個(gè)子類,為了快速使用,可以直接實(shí)例化一個(gè)抽象類,并當(dāng)場(chǎng)實(shí)現(xiàn)其抽象方法。既然實(shí)現(xiàn)了抽象方法,那么這就是一個(gè)新的類,只是個(gè)類沒有命名,這樣的類就叫做匿名類。如下:
public abstract void attack(); //該抽象方法的抽象類 Hero h = new Hero(){ //實(shí)例化抽象類時(shí)直接實(shí)現(xiàn)抽象方法//當(dāng)場(chǎng)實(shí)現(xiàn)attack方法public void attack() {System.out.println("新的進(jìn)攻手段");}};內(nèi)部類和匿名類的區(qū)別是:內(nèi)部類聲明在外部類成員的位置,而本地類和匿名類是聲明在代碼塊里面的,可以是主方法或for循環(huán)的代碼塊里面的。
public static void main(String[] args) {//與匿名類的區(qū)別在于,本地類有了自定義的類名class SomeHero extends Hero{ //內(nèi)部本地類public void attack() {System.out.println( name+ " 新的進(jìn)攻手段");}}SomeHero h =new SomeHero();h.name ="地卜師";h.attack(); }?
22、接口默認(rèn)方法是JDK8新特性,指的是接口也可以提供具體方法了,而不像以前,只能提供抽象方法。Mortal 這個(gè)接口,增加了一個(gè)默認(rèn)方法?revive,這個(gè)方法有實(shí)現(xiàn)體,并且被聲明為了default
package charactor;public interface Mortal {public void die();default public void revive() {System.out.println("本英雄復(fù)活了");} }優(yōu)點(diǎn):假設(shè)沒有默認(rèn)方法這種機(jī)制,那么如果要為Mortal增加一個(gè)新的方法revive,那么所有實(shí)現(xiàn)了Mortal接口的類,都需要做改動(dòng)。但是引入了默認(rèn)方法后,原來(lái)的實(shí)現(xiàn)類,不需要做任何改動(dòng),并且還能得到這個(gè)默認(rèn)方法。通過(guò)這種手段,就能夠很好的擴(kuò)展新的類,并且做到不影響原來(lái)的類
?
23、UML圖的理解和使用
理解:UML-unified module language 統(tǒng)一建模語(yǔ)言,可以很方便的描述類的屬性、方法、以及類和類之間的關(guān)系。
使用:其中修飾符#表示protected ,修飾符+表示 default,方法有下劃線表示是構(gòu)造方法,方法是斜體表示是抽象方法,帶箭頭的實(shí)線表示繼承,帶箭頭的虛線表示實(shí)現(xiàn)接口。
?
?
更多資源或?qū)崙?zhàn)項(xiàng)目詳細(xì)可以了解:http://how2j.cn/k/interface-inheritance/interface-inheritance-practise/679.html?p=29570
總結(jié)
以上是生活随笔為你收集整理的java基础学习笔记(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【深度学习】真正的即插即用!盘点11种C
- 下一篇: 【学术相关】为什么很多国内学者的AI的论