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