Java基礎學習筆記(狂神說版)
三、Java方法
(一)方法的重載
1. 重載的概念:
重載就是在一個類中,有相同的函數名稱,形參不同的函數。
2. 方法重載的規則:
(1)方法名必須相同
(2)參數列表必須不同(個數不同、或類型不同、參數排列順序不同等)
(3)方法的返回類型可以相同,也可以不同
(4)僅僅返回類型不同不足以成為方法的重載
3. 實現理論:
方法名稱相同時,編譯器會根據調用方法的參數個數,參數類型去逐個匹配,以選擇對應的方法,如果匹配失敗,則編譯器報錯
(二)方法的可變參數
可變參數(不定項參數):
JDK1.5開始,Java支持傳遞同類型的可變參數給一個方法
在方法聲明中,在指定參數類型中加一個省略號(...)
一個方法中只能指定一個可變參數,他必須是方法的最后一個參數,普通參數聲明必須在其之前
(三)方法的遞歸
遞歸就是:A方法調用A方法!就是自己調用自己
遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算,大大減少了程序的代碼量。遞歸的能力在於用有限的語句定義對的無限集合。
遞歸結構包括兩個部分:
(1)遞歸頭:什么時候不調用自身方法。如果沒有頭,將陷入死循環。
(2)遞歸體:什么時候需要調用自身方法。
四、Java數組
(一)數組的概念
數組的定義:
數組是相同類型數據的有序集合。
數組描述的是相同類型的若干個數據,按照一定的先后次序排列組合而成。
其中,每一個數據稱作一個數組元素,每個數組元素可以通過一個下標來訪問他們。
數組的四個基本特點:
(1)其長度是確定的。數組一旦被創建,它的大小就是不可以被改變的。
(2)其元素必須是相同類型,不允許出現混合類型。
(3)數組中的元素可以是任何數據類型,包括基本類型和引用類型。
(4)數組變量屬引用類型,數組也可以看成是對象,數組中的每個元素相當於該對象的成員變量。數組本身就是對象,Java中對象是在堆中的,因此數組無論保存原始類型還是其他對象類型,數組對象本身是在堆中的。
(二)數組的使用
1. 數組初始化的方式:
(1) 靜態初始化
int[] a = {1,2,3};
Man[] mans = {new Man(1,1),new Man(2,2)};
(2)動態初始化
int[] a = new int[2];
a[0]=1;
a[2]=2;
2. 數組的默認初始化:
數組是引用類型,它的元素相當於類的實例變量,因此數組一經分配空間,其中每個元素也被按照實例變量同樣的方法被隱式初始化。
package array;
public class ArrayDemo01 {
public static void main(String[] args) {
//靜態初始化:創建+ 賦值
int[] a = {1,2,3,4,5,6,7,8};
System.out.println(a[0]);
//動態初始化:包含默認初始化
int [] b = new int[20];
b[0] = 1;
System.out.println(b[0]);
System.out.println(b[1]);
System.out.println(b[2]);
System.out.println(b[3]);
}
}
- 數組堆棧分析:
//聲明數組,array進入棧內存
int array = null;
//創建數組,new關鍵字操作進入堆內存中
array = new int[10];
//給數組元素中賦值
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
nums[4] = 5;
nums[5] = 6;
nums[6] = 7;
nums[7] = 8;
4. 數組邊界:
下標的合法區間:[0,length-1],如果越界就會報錯:
public class ArrayDemo02 {
public static void main(String[] args) {
int [] a = new int [2];
System.out.println(a[2]);
}
}
java.lang.ArrayIndexOutOfBoundsException:數組下標越界異常!
(三)小結
數組是相同數據類型(數據類型可以為任意類型)的有序集合。
數組也是對象。數組元素相當於對象的成員變量。
數組長度的確定性,不可變的,如果越界,則報:ArrayIndexOutOfBoundsException
數組的使用:
(1)普通的for循環
(2)For-Each循環
(3)數組做方法入參
(4)數組做返回值
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5};
//打印全部的數組元素
for(int i = 0;i<arrays.length;i++){
System.out.println(arrays[i]);
}
System.out.println("==================");
//計算所以元素的和
int sum = 0;
for(int i = 0;i < arrays.length;i++) {
sum += arrays[i];
}
System.out.println("sum="+sum);
System.out.println("=====================");
//查找最大元素
int max = arrays[0];
for (int i = 1;i<arrays.length;i++){
if(arrays[i]>max){
max = arrays[i];
}
}
System.out.println("max="+max);
}
}
public class ArrayDemo04 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5};
int[] reverse = reverse(arrays);
printArray(reverse);
}
//反轉數組
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
//反轉操作
for (int i = 0,j = result.length-1; i < arrays.length; i++,j--){
result[j] = arrays[i];
}
return result;
}
//打印數組元素
public static void printArray(int[] arrays){
for (int i = 0; i < arrays.length;i++){
System.out.println(arrays[i]+"");
}
}
}
(四)多維數組
1. 多維數組:
多維數組可以看成是數組的數組,比如二維數組就是一個特殊的一維數組,其每一個元素都是一個一維數組。
2. 二維數組:
int a[][] = new int[2][5];
解析:二位數組a可以看成一個兩行三列的數組。
3. 圖解二位數組:
4. Arrays類:
數組的工具類java.util.Arrays(查看JDK幫助文檔)
由於數組對象本身並沒有什么方法可以供我們調用,但API中提供了一個工具類Arrays供我們使用,從而可以對數據對象進行一些基本的操作。
注意:Arrays類中的方法都是static修飾的靜態方法,在使用的時候可以直接使用類名進行調用,而“不用”使用對象來調用(注意:是“不用”而不是“不能”)
5. 具有以下常用功能:
給數組賦值:通過fill方法。
對數組排序:通過sort方法,按升序。
比較數組:通過equals方法對比數組中元素是否值得等待。
查找數據元素:通過biarySearch方法能對排序好的數組進行二分法查找法操作。
(五)排序算法和稀疏數組算法
1. 冒泡排序-時間復雜度為O(n2):冒泡排序是八大排序算法之一。
冒泡的代碼還是相當簡單的,兩層循環,外層冒泡輪數 ,里面依次比較。
package array;
import java.lang.reflect.Array;
import java.util.Arrays;
//冒泡排序
//1.比較數組中,兩個相鄰的元素,如果第一個數比第二個數大,我們就交換他的位置
//2.梅一次比較,都會產生一個最大,或者最小的數字;
//下一輪則可以少一次排序!
//4.依次循環,直到結束!
public class ArrayDemo06 {
public static void main(String[] args) {
int[] a = {1, 4, 5, 6, 72, 2, 2, 2, 25, 6, 7};
//調用完我們自己寫的排序方法后,返回一個排序后的數組
int[] sort = sort(a);
System.out.println(Arrays.toString(sort));
}
public static int[] sort(int[] array) {
//臨時變量
int temp = 0;
//外層循環,判斷我們要循環多少次
for (int i = 0; i < array.length - 1; i++) {
//通過flag標識位減少沒有意義的比較
boolean flag = false;
//內層循環,比價判斷兩個數,如果第一個數,比第二個數大,則交換位置
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j + 1] > array[j]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
flag = true;
}
}
if (flag == false) {
break;
}
}
return array;
}
}
2. 稀疏數組:
當一個數組中大部分元素為0,或者為同一值的數組時,可以使用稀疏數組來保存該數組。
稀疏數組的處理方式是:
記錄數組一共有幾行幾列,有多少不同值。
把具有不同值的元素和行列及值記錄在一個小規模的數組中,從而縮小程序的規模。
package array;
public class ArrayDemo07 {
public static void main(String[] args) {
//1.創建一個二維數組 11*11 0:沒有棋子 1:黑棋 2:白棋
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//輸出原始的數組
System.out.println("輸出原始的數組");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
//換行
System.out.println();
}
System.out.println("==========================");
//轉換為稀疏數組
//獲取有效值的個數
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j <11 ; j++) {
if (array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值的個數"+sum);
//2.創建一個稀疏數組的數組
int[][] array2 = new int[sum + 1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//遍歷 二維數組,將非零的值,存放稀疏數組中
int count = 0;
for (int i = 0; i <array1.length ; i++) {
for (int j = 0; j <array1[i].length ; j++) {
if (array1[i][j]!=0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
//輸出稀疏數組
System.out.println("稀疏數組");
for (int i = 0; i <array2.length ; i++) {
System.out.println(array2[i][0]+"\t"
+array2[i][1]+"\t"
+array2[i][2]+"\t"
);
}
System.out.println("======================");
System.out.println("還原");
//1.讀取稀疏數組
int[][] array3 = new int[array2[0][0]][array2[0][1]];
//2.給其中的元素還原它的值
for (int i = 1; i <array2.length ; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//3.打印
System.out.println("輸出還原的數組");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
}
}
五、面向對象
(一)面向對象&面向過程
1. 面向過程思想:
步驟清晰簡單,第一步做什么,第二部做什么...
面向過程適合處理一些較為簡單的問題。
2. 面向對象思想:
物以類聚,分類的思維模式,解決問題首先會思考問題需要哪些分類,然后對這些分類進行獨立思考。
最后,才對某個分了問題下的細節進行面向過程的思索。
面向對象適合處理復雜的問題,適合處理需要多人協作的問題。
對於描寫復雜的事務,為了從宏觀上把握,從整體上合理分析,我們需要使用面向對象的思路來分析整個系統。但是,具體到微觀操作,仍然需要面向過程的思路去處理。
3. 面向對象編程(OOP)
面向對象編程的本質:以類的方式組織代碼,以對象的形式封裝數據
4. 抽象
(1)從認識論角度考慮是先有對象后有類。對象,是具體的事物。類,是抽象的,是對對象的抽象。
(2)從代碼運行的角度考慮是先有類后有對象。類是對象的模板。
(二)方法的調用
1. 靜態方法和非靜態方法(static修飾方法名)
(1)靜態方法調用:類名.方法名
(2)非靜態方法調用:實例化類(new)
//對象類型 對象名稱 = 對象值
Student student = new Student();
//對象名字.方法名
student.say();
2. 值傳遞與引用傳遞
//值傳遞
public class Demo04{
public static void main(String[] args){
int a = 1;
System.out.println(a);//1
Demo04.change(a);
System.out.println(a);//1
}
public static void change(int a){
a = 10;
}
}
//引用傳遞:對象,本質還是值傳遞
//理解對象的概念,了解內存的知識
public class Demo05{
public static void main(String[] args){
Person person = mew Perosn();
System.out.println(person.name);//null
Demo05.change(person);
System.out.println(person.name);//111
}
public static void change(Person person){
//person是一個對象,指向的---->Person person = new Person();這是一個具體的人,可以改變屬性!
person.name = "111";
}
}
class person{
String name;//null
}
3. 類與對象的創建
//學生類
public static Student(){
//屬性:字段
String name;
int age;
//方法
public void study
/*this 關鍵字用來表示當前對象本身,或當前類的一個實例
通過 this 可以調用本對象的所有方法和屬性。*/
System.out.println(this.name + "在學習");
}
public static void main(String[] args){
//類:抽象的,實例化
//類實例化后會返回一個自己的對象!
//student對象就是一個Student類的具體實例!
Student xm = new Student();
Student xh = new Student();
xm.name = "小明";
xm.age = "3";
System.out.println(xm.name);
System.out.println(xm.age);
xh.name = "小紅";
xh.agh = "3";
System.out.println(xh.name);
System.out.println(xh.age);
}
}
4. 創建與初始化對象
使用new關鍵字創建對象
使用new關鍵字創建的時候,除了分配內存空間之外,還會給創建好的對象進行默認初始化以及對類中構造器的調用。
5. 類的構造器也被稱為構造方法,是在進行常見對象的時候必須調用的。並且構造器有以下幾個特點:
1.必須和類的名字相同
2.必須沒有返回類型,也不能寫void
6. 作用:
(1)new本質就是在調用構造方法
(2)初始化對象的值
7. 注意點:
定義有參構造之后,如果想使用無參構造,顯示的定義一個無參的構造(alt+ Insert)
public class Person {
String name ;
int age ;
public Person() {
}
//有參構造:一旦定義
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class Application {
public static void main(String[] args) {
//實例化了一個對象
Person person = new Person( "aaaa " ,1);
System.out.println(person.name);
}
}
(三)封裝
封裝的概念:
該露的露,該藏的藏
我們的程序設計要追求“高內聚,低耦合”。高內聚就是類的內部數據操作細節自己完成,不允許外部干涉;低耦合:僅暴露少量的方法給外部使用。
封裝(數據的隱藏)。通常,應禁止直接訪問一個對象中數據的實際表示,而應通過操作接口來訪問,這稱為信息隱藏。
屬性私有,get/set
(四)繼承
1. 繼承的概念:
繼承的本質是對某一批類的抽象,從而實現對現實世界更好的建模。
extands的意思是“擴展”。子類是父類的擴展。
JAVA中類只有單繼承,沒有多繼承!
繼承是類和類之間的一種關系。除此之外,類和類之間的關系還有依賴、組合、聚合等。
繼承關系的兩個類,一個為子類(派生類),一個為父類(基類)。子類繼承父類,使用extends來表示。子類和父類之間,從意義上講應該具有“is a”的關系。
2. Object類
3. super注意點:
(1)super調用父類的構造方法,必須在構造方法的第一個。
(2)super必須只能出現在子類或者構造方法中!
(3)super和this不能同時調用構造方法!
4. super vs this:
(1)代表的對象不同:this本身調用者這個對象 / super代表父類對象的應用。
(2)前提:this沒有繼承也可以使用 / super只能在繼承條件才可以使用。
(3)構造方法:this();本類的構造 / super();父類的構造。
5. 方法重寫:需要有繼承關系,子類重寫父類的方法!
(1)方法名必須要相同
(2)參數列表必須相同。
(3)修飾符:范圍可以擴大但不能縮小。 public>Protected>Default>private
(4)拋出的異常:范圍,可以被縮小,但不能擴大。 ClassNotFoundException- >Exception(大)
重寫,子類的方法必須要和父類一致,方法體不同!
6. 為什么要重寫:
父類的功能,子類不一定需要,或者不一定滿足!Alt+Insert; override;
(五)多態
1. 多態的概念
多態:即同一個方法可以根據發送對象的不同而采用多種不同的行為方式。
一個對象的實際類型是確定的,但可以指向對象的引用的類型有很多(父類,有關心的類)。
2. 多態存在的條件:
(1)有繼承關系。
(2)子類重寫父類方法。
(3)父類引用指向子類對象。
注意:多態是方法的多態,屬性是沒有多態性的。
3. instanceof(類型轉換)引用類型,判斷一個對象是什么類型:
(1)父類引用指向子類對象;
(2)把子類轉換為父類,向上轉型;
(3)把父類轉換為子類,向下轉型:強制轉換
(4)方便方法的調用,減少重復的代碼!