目錄
java基礎知識
-
Java語言跨平臺原理(理解)
Java程序並非是直接運行的,Java編譯器將Java源程序編譯成與平臺無關的字節碼文件(class文件),然後由Java虛 擬機(JVM)對字節碼文件解釋執行。所以在不同的操作系統下,只需安裝不同的Java虛擬機即可實現java程序的 跨平臺。
-
JRE(Java Runtime Environment)
是java程序的運行時環境,包含 jvm 和運行時所需的核心類庫。
-
JDK(Java Development Kit)
是java程序開發工具包,包含JRE和開發人員使用的開發工具
開發工具:編譯工具(javac.exe),運行工具(java.exe)。
-
關鍵字:
特點關鍵字字母全部都是小寫
關鍵字 | 含義 |
abstract | 表明類或者成員方法具有抽象屬性 |
assert | 斷言,用來進行程序調試 |
boolean | 基本數據類型之一,聲明布爾類型的關鍵字 |
break | 提前跳出一個塊 |
byte | 基本數據類型之一,字節類型 |
case | 用在switch語句之中,表示其中的一個分支 |
catch | 用在異常處理中,用來捕捉異常 |
char | 基本數據類型之一,字符類型 |
class | 聲明一個類 |
const | 保留關鍵字,沒有具體含義 |
continue | 回到一個塊的開始處 |
default | 默認,例如,用在switch語句中,表明一個默認的分支。Java8 中也作用於聲明接口函數的默認實現 |
do | 用在do-while循環結構中 |
double | 基本數據類型之一,雙精度浮點數類型 |
else | 用在條件語句中,表明當條件不成立時的分支 |
enum | 枚舉 |
extends | 表明一個類型是另一個類型的子類型。對於類,可以是另一個類或者抽象類;對於接口,可以是另一個接口 |
final | 用來說明最終屬性,表明一個類不能派生出子類,或者成員方法不能被覆蓋,或者成員域的值不能被改變,用來定義常量 |
finally | 用於處理異常情況,用來聲明一個基本肯定會被執行到的語句塊 |
float | 基本數據類型之一,單精度浮點數類型 |
for | 一種循環結構的引導詞 |
goto | 保留關鍵字,沒有具體含義 |
if | 條件語句的引導詞 |
implements | 表明一個類實現了給定的接口 |
import | 表明要訪問指定的類或包 |
instanceof | 用來測試一個對象是否是指定類型的實例對象 |
int | 基本數據類型之一,整數類型 |
interface | 接口 |
long | 基本數據類型之一,長整數類型 |
native | 用來聲明一個方法是由與計算機相關的語言(如C/C++/FORTRAN語言)實現的 |
new | 用來創建新實例對象 |
package | 包 |
private | 一種訪問控制方式:私用模式 |
protected | 一種訪問控制方式:保護模式 |
public | 一種訪問控制方式:共用模式 |
return | 從成員方法中返回數據 |
short | 基本數據類型之一,短整數類型 |
static | 表明具有靜態屬性 |
strictfp | 用來聲明FP_strict(單精度或雙精度浮點數)表達式遵循IEEE 754算術規範 |
super | 表明當前對象的父類型的引用或者父類型的構造方法 |
switch | 分支語句結構的引導詞 |
synchronized | 表明一段代碼需要同步執行 |
this | 指向當前實例對象的引用 |
throw | 拋出一個異常 |
throws | 聲明在當前定義的成員方法中所有需要拋出的異常 |
transient | 聲明不用序列化的成員域 |
try | 嘗試一個可能拋出異常的程序塊 |
void | 聲明當前成員方法沒有返回值 |
volatile | 表明兩個或者多個變量必須同步地發生變化 |
while | 用在循環結構中 |
-
計算機的存儲單元:
計算機存儲設備的最小信息單元叫: 位(bit)/比特位(b)
計算機最小的存儲單元叫:字節 (byte)通常用大寫字母B表示,字節是連續的8個位組成
換算公式:
1B(字節)=8bit(b)
1KB=1024B
1MB=1024KB
1G=1024MB
1T=1024G
-
數據類型
數據類型 |
關鍵字 |
內存佔用 |
取值範圍 |
整數類型
|
byte |
1 |
-128~127 |
short |
2 |
-32768~32767 |
|
int(默認) |
4 |
-2的31次方到2的31次方-1 |
|
long |
8 |
-2的63次方到2的63次方-1 |
|
浮點類型
|
float |
4 |
負數:-3.402823E+38到-1.401298E-45 正數: 1.401298E-45到 3.402823E+38 |
double(默認) |
8 |
負數:-1.797693E+308到-4.9000000E-324 正數:4.9000000E-324 到 1.797693E+308 |
|
字符類型 |
char |
2 |
0-65535 |
布爾類型 |
boolean |
1 |
true,false |
說明:e+38表示是乘以10的38次方,同樣,e-45表示乘以10的負45次方。在java中整數默認是int類型,浮點數默認是double類型。
-
標識符:就是給類,方法,變量等起名字的符號
Java中標識符的組成規則:
-
由字母、數字、下劃線“_”、美元符號“$”組成
-
不能以數字開頭。
-
不能是關鍵字。
-
區分大小寫。
Java中標識符的命名約定:
-
小駝峯式命名:變量名、方法名
首字母小寫,從第二個單詞開始每個單詞的首字母大寫。
-
大駝峯式命名:類名
每個單詞的首字母都大寫。
另外,標識符的命名最好可以做到見名知意
-
數據類型轉換
自動類型轉換
//String轉數字類型
String s = "169";
byte b = Byte.parseByte( s );
short t = Short.parseShort( s );
int i = Integer.parseInt( s );
long l = Long.parseLong( s );
Float f = Float.parseFloat( s );
Double d = Double.parseDouble( s );
//數字類型轉String
String a = Integer.toString(num);
-
算術運算符
符號 |
作用 |
說明 |
+ |
加 |
參看小學一年級 |
- |
減 |
參看小學一年級 |
* |
乘 |
參看小學二年級,與“×”相同 |
/ |
除 |
參看小學二年級,與“÷”相同 |
% |
取餘 |
獲取的是兩個數據做除法的餘數 |
小數取整:
Math.ceil()執行向上舍入,即它總是將數值向上舍入爲最接近的整數,返回值爲Double類型;
Math.floor()執行向下舍入,即它總是將數值向下舍入爲最接近的整數,返回值爲Double類型;
Math.round()執行標準舍入,即它總是將數值四捨五入爲最接近的整數,返回值爲Long類型;
-
賦值運算符
符號 |
作用 |
說明 |
= |
賦值 |
a=10,將10賦值給變量a |
+= |
加後賦值 |
a+=b,將a+b的值給a |
-= |
減後賦值 |
a-=b,將a-b的值給a |
*= |
乘後賦值 |
a*=b,將a×b的值給a |
/= |
除後賦值 |
a/=b,將a÷b的商給a |
%= |
取餘後賦值 |
a%=b,將a÷b的餘數給a |
注意:擴展的賦值運算符隱含了強制類型轉(+=,-=,*=,/=,%=)
short num = 10;
num += 20; //正常: += 封裝了強制類型轉換,等價於num = (short)(num + 20);
num = num + 20; // 報錯: num + 20 返回值爲int,但是num是short類型
符號 |
作用 |
說明 |
<< |
左移運算符 |
例如8<<2,表示將8向左移2位,結果爲32。低位補0。二進制演算:8的二進制:1 0 0 0向左移動兩位結果爲1 0 0 0 0 0,換算成十進制即爲32,也可以簡單的理解爲,左移就是將數變大,相當於8*2^2=32。 |
>> |
右移運算符 |
例如 8>>2,表示將8向右移動2位,結果爲2。高位補0。 |
-
自增自減運算符
符號 |
作用 |
說明 |
++ |
自增 |
變量的值加1 |
-- |
自減 |
變量的值減1 |
注意事項:
++和-- 既可以放在變量的後邊,也可以放在變量的前邊。
單獨使用的時候, ++和-- 無論是放在變量的前邊還是後邊,結果是一樣的。
參與操作的時候,如果放在變量的後邊,先拿變量參與操作,後拿變量做++或者--。參與操作的時候,如果放在變量的前邊,先拿變量做++或者--,後拿變量參與操作。最常見的用法:單獨使用。
自加自減的操作在當前表達式就已經完成
int i = 10;
int j = i++;
int y = 10;
int x = ++y;
System.out.println(i); //11
System.out.println(j); //10
System.out.println(y); //11
System.out.println(x); //11
-
邏輯運算符
符號 |
作用 |
說明 |
& |
邏輯與 |
a&b,a和b都是true,結果爲true,否則爲false |
| |
邏輯或 |
a|b,a和b都是false,結果爲false,否則爲true |
^ |
邏輯異或 |
a^b,a和b結果不同爲true,相同爲false |
! |
邏輯非 |
!a,結果和a的結果正好相反 |
邏輯異或:相同爲false,不同爲true
System.out.println((1>2) ^ (1<2));//false ^ true //true
System.out.println((1<2) ^ (1>2));//true ^ false //true
System.out.println((1<2) ^ (1<2));//true ^ true //false
System.out.println((1>2) ^ (1>2));//false ^ false //false
-
短路邏輯運算符
符號 |
作用 |
說明 |
&& |
短路與 |
作用和&相同,但是有短路效果 |
|| |
短路或 |
作用和|相同,但是有短路效果 |
在邏輯與運算中,只要有一個表達式的值爲false,那麼結果就可以判定爲false了,沒有必要將所有表達式的值都計算出來,短路與操作就有這樣的效果,可以提高效率。同理在邏輯或運算中,一旦發現值爲true,右邊的表達式將不再參與運算。
-
三元運算符
關係表達式 ? 表達式1:表達式2
解釋:問號前面的位置是判斷的條件,判斷結果爲boolean型,爲true時調用表達式1,爲false時調用表達式2。其邏輯爲:如果條件表達式成立或者滿足則執行表達式1,否則執行第二個。
int a = 10;
int b = 20;
int result3 = a > b ? a:b;
System.out.println("max: " + result3);
int result4 = a < b ? a:b;
System.out.println("min: " + result4);
//-------------------------------------result----------------------------
max: 20
min: 10
-
流程控制語句
-
順序結構
順序結構: 是程序中最簡單最基本的流程控制,沒有特定的語法結構,按照代碼的先後順序,依次執行,程序中大多數的代碼都是這樣執行的。
-
分支結構(if, switch)
①首先計算關係表達式的值
②如果關係表達式的值爲true就執行語句體
③如果關係表達式的值爲false就不執行語句體
④繼續執行後面的語句內容
-
循環結構(for, while, do…while)
-
switch case穿透
注意事項: 在switch case語句中,如果case控制的語句後面不寫break,將會出現穿透現象,在不判斷下一個case值的情況下繼續向下運行,直到遇到break或者switch case語句結束。
int value = 5;
switch(value){
case 1:
case 4:
case 7:
System.out.println("1是地主");
break;
case 2:
case 5:
case 8:
System.out.println("2是地主");
break;
case 3:
case 6:
case 9:
System.out.println("3是地主");
break;
default:
System.out.println("都不是地址");
//-------------------------result-----------------------
2是地主
int value = 5;
switch(value) {
case 1:
System.out.println("111111");
case 4:
case 7:
System.out.println("1是地主");
break;
case 2:
case 5:
System.out.println("55555555");
case 12:
System.out.println("12121212");
case 8:
System.out.println("2是地主");
break;
case 3:
case 6:
case 9:
System.out.println("3是地主");
break;
default:
System.out.println("都不是地址");
}
//-------------------------result-----------------------
55555555
12121212
2是地主
-
三種循環的區別
三種循環的區別
for循環和while循環先判斷條件是否成立,然後決定是否執行循環體(先判斷後執行)
do...while循環先執行一次循環體,然後判斷條件是否成立,是否繼續執行循環體(先執行後判斷)
for循環和while的區別
條件控制語句所控制的自增變量,因爲歸屬for循環的語法結構中,在for循環結束後,就不能再次被訪問到了
條件控制語句所控制的自增變量,對於while循環來說不歸屬其語法結構中,在while循環結束後,該變量還可以繼續使用
死循環(無限循環)的三種格式
-
for(;;){}
-
while(true){} (最常用)
-
do {} while(true);
int n = 5;
while (++n <= 10) {
System.out.println(n);
}
System.out.println("-------------------");
int i = 5;
while (i++ <= 10) {
System.out.println(i);
}
//-------------------------result---------------------------------
6
7
8
9
10
-------------------
6
7
8
9
10
11
-
獲取隨機數 Random
Random random = new Random();
int ra = random.nextInt(10);
//10代表的是一個範圍,如果括號寫10,產生的隨機數就是0-9,包含下限,不包含上限
System.out.println(ra);
-
IDEA常用快捷鍵
快捷鍵 |
功能 |
Alt+Enter |
導入包,自動修正代碼 |
Ctrl+Y |
刪除光標所在行 |
Ctrl+D |
複製光標所在行的內容,插入光標位置下面 |
Ctrl+Alt+L |
格式化代碼 |
Ctrl+/ |
單行註釋 |
Ctrl+Shift+/ |
選中代碼註釋,多行註釋,再按取消註釋 |
Alt+Shift+上下箭頭 |
移動當前代碼行 |
Ctrl+B | 查看方法源碼 |
ALT+7 | 查看類的成員變量、方法目錄 |
Ctrl+Alt+V | 自動補齊等號左邊的聲明代碼 |
Ctrl+Shift+V | 查看粘貼板歷史內容 |
ctrl + alt +B | 查找接口的實現類 |
ALT +INSERT | 快速實現接口快捷方式 |
內容輔助鍵
Ctrl + Alt +space: 內容提示,代碼補全等
快速生成語句
快速生成main()方法: psvm + 回車
快速生成輸出語句: sout + 回車
-
數組
常用輸出格式:
int[] arr = new int[10];
System.out.println(Arrays.toString(arr));
String[] arrstr = new String[10];
System.out.println(Arrays.toString(arrstr));
//--------------result-------------------
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[null, null, null, null, null, null, null, null, null, null]
數組定義格式
第一種: 數據類型[] 數組名 int[] arr = new int[]; (常用第一種)
定義了一個int類型的數組,數組名是arr
第二種: 數據類型 數組名[] int arr[] = new int[];
定義了一個int類型的變量,變量名是arr數組
數組靜態初始化
在創建數組時,指定每個元素的初始值,有系統決定數組長度
格式: 數據類型[] 數組名 = new 數據類型[]{元素1, 元素2, 元素3...}
簡化格式:數據類型[] 數組名 = {元素1, 元素2, 元素3...}
數組動態初始化
數組動態初始化就是隻給定數組的長度,由系統給出默認初始化值
整數默認爲:0
浮點數默認爲:0.0
布爾值默認爲: false
字符默認爲: 空格(空字符)
引用數據類型默認爲:null (Double,Float等是null)
char[] ch = new char[1];
System.out.println(ch[0]); //空格
if(ch[0] =='\0'){
System.out.println("ch[0] is space"); //ch[0] is space
}
String[] arr2 = new String[1];
System.out.println(arr2[0]); //null
int[] arr1 = new int[1];
System.out.println(arr1[0]); //0
double[] dou = new double[1];
System.out.println(dou[0]); //0.0
Double[] dob = new Double[1];
System.out.println(dob[0]); //null
float[] flo = new float[1];
System.out.println(flo[0]); //0.0
Float[] flot = new Float[1];
System.out.println(flot[0]); //null
-
內存分配
int[] arr = new int[3];
- 棧內存:存儲局部變量(定義在方法中的變量),例如arr,使用完畢立即消失
- 堆內存:存儲new出來的內容(實體,對象)
數組在初始化時,會爲存儲空間添加默認值:
整數默認爲:0
浮點數默認爲:0.0
布爾值默認爲: false
字符默認爲: 空格(空字符)
引用數據類型默認爲:null (Double,Float等是null)
每一個new出來的東西都有一個地址值,使用完畢,會在垃圾回收器空閒時被回收
區域名稱 |
作用 |
寄存器 |
給CPU使用,和我們開發無關。 |
本地方法棧 |
JVM在使用操作系統功能的時候使用,和我們開發無關。 |
方法區 |
存儲可以運行的class文件。 |
堆內存 |
存儲對象或者數組,new來創建的,都存儲在堆內存。 |
方法棧 |
方法運行時使用的內存,比如main方法運行,進入方法棧中執行。 |
-
for多個條件控制
int[] arr = new int[]{1,2,3,45,6,7,8,9,10};
for(int i=0,j=arr.length-1; i<=j; i++,j--){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
-
類和對象的理解
類的理解
類是對現實生活中一類具有共同屬性和行爲的事物的抽象
類是對象的數據類型,類是具有相同屬性和行爲的一組對象的集合簡單理解:類就是對現實事物的一種描述類的組成
屬性:指事物的特徵,例如:手機事物(品牌,價格,尺寸)
行爲:指事物能執行的操作,例如:手機事物(打電話,發短信)類和對象的關係
類:類是對現實生活中一類具有共同屬性和行爲的事物的抽象對象:是能夠看得到摸的着的真實存在的實體
簡單理解:類是對事物的一種描述,對象則爲具體存在的事物
類的組成是由屬性和行爲兩部分組成
屬性:在類中通過成員變量來體現(類中方法外的變量)
行爲:在類中通過成員方法來體現(和前面的方法相比去掉static關鍵字即可)類的定義
-
成員變量和局部變量
成員變量和局部變量的區別
類中位置不同:成員變量(類中方法外)局部變量(方法內部或方法聲明上)內存中位置不同:成員變量(堆內存)局部變量(棧內存)
生命週期不同:成員變量(隨着對象的存在而存在,隨着對象的消失而消失)局部變量(隨着方法的調用而存在,醉着方法的調用完畢而消失)
初始化值不同:成員變量(有默認初始化值)局部變量(沒有默認初始化值,必須先定義,賦值才能使用)
-
創建字符串對象兩種方式的區別
通過 new 創建的字符串對象,每一次 new 都會申請一個內存空間,雖然內容相同,但是地址值不同 直接賦值方式創建
以“”方式給出的字符串,只要字符序列相同(順序和大小寫),無論在程序代碼中出現幾次,JVM 都只會建立一個 String 對象,並在字符串池中維護
-
字符串的比較
比較基本數據類型:比較的是具體的值
比較引用數據類型:比較的是對象地址值
equals方法的作用
比較的是具體的值
-
StringBuilder類和String類的區別
String類:內容是不可變的
StringBuilder類:內容是可變的
-
StringBuilder和String相互轉換
StringBuilder轉換爲String
public String toString():通過 toString() 就可以實現把 StringBuilder 轉換爲 String
String轉換爲StringBuilder
public StringBuilder(String s):通過構造方法就可以實現把 String 轉換爲 StringBuilder
-
ArrayList類概述
什麼是集合
提供一種存儲空間可變的存儲模型,存儲的數據容量可以發生改變
ArrayList集合的特點
底層是數組實現的,長度可以變化 泛型的使用
用於約束集合中存儲元素的數據類型
構造方法
方法名 |
說明 |
public ArrayList() |
創建一個空的集合對象 |
成員方法
方法名 |
說明 |
public boolean remove(Object o) |
刪除指定的元素,返回刪除是否成功 |
public E remove(int index) |
刪除指定索引處的元素,返回被刪除的元素 |
public E set(int index,E element) |
修改指定索引處的元素,返回被修改的元素 |
public E get(int index) |
返回指定索引處的元素 |
public int size() |
返回集合中的元素的個數 |
public boolean add(E e) |
將指定的元素追加到此集合的末尾 |
public void add(int index,E element) |
在此集合中的指定位置插入指定的元素 |
ArrayList<Integer> test = new ArrayList<Integer>();
test.add(9).add(8).add(7).add(6);
System.out.println(test);
//System.out.println(test.remove(9)); 錯誤的做法,此處的9會認爲是索引而非元素
System.out.println(test.remove((Integer)9));
System.out.println(test);
-
封裝
-
封裝概述 是面向對象三大特徵之一(封裝,繼承,多態) 是面向對象編程語言對客觀世界的模擬,客觀世界裏成員變量都是隱藏在對象內部的,外界是無法直接操作的
-
封裝原則 將類的某些信息隱藏在類內部,不允許外部程序直接訪問,而是通過該類提供的方法來實現對隱藏信息的操作和訪問 成員變量private,提供對應的getXxx()/setXxx()方法
-
封裝好處 通過方法來控制成員變量的操作,提高了代碼的安全性 把代碼用方法進行封裝,提高了代碼的複用性
-
繼承
繼承的概念
繼承是面向對象三大特徵之一,可以使得子類具有父類的屬性和方法,還可以在子類中重新定義,以及追加屬性和方法實現繼承的格式
繼承通過extends實現
格式:class 子類 extends 父類 { }
舉例:class Dog extends Animal { }
-
繼承的好處和弊端
繼承好處
- 提高了代碼的複用性(多個類相同的成員可以放到同一個類中)
- 提高了代碼的維護性(如果方法的代碼需要修改,修改一處即可)
繼承弊端
繼承讓類與類之間產生了關係,類的耦合性增強了,當父類發生變化時子類實現也不得不跟着變化,削弱了子類的獨立性
繼承的應用場景:
使用繼承,需要考慮類與類之間是否存在is..a的關係,不能盲目使用繼承
is..a的關係:誰是誰的一種,例如:老師和學生是人的一種,那人就是父類,學生和老師就是子類
-
super
this:代表本類對象的引用
super:代表父類存儲空間的標識(可以理解爲父類對象引用) this和super的使用分別
this和super的區別
-
繼承中構造方法的訪問特點
注意:子類中所有的構造方法默認都會訪問父類中無參的構造方法
子類會繼承父類中的數據,可能還會使用父類的數據。所以,子類初始化之前,一定要先完成父類數據的初始化,原因在於,每一個子類構造方法的第一條語句默認都是:super()
-
方法重寫
- 方法重寫概念
子類出現了和父類中一模一樣的方法聲明(方法名一樣,參數列表也必須一樣)
- 方法重寫的應用場景
當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容
- Override註解
用來檢測當前的方法,是否是重寫的方法,起到【校驗】的作用
方法重寫的注意事項
- 私有方法不能被重寫(父類私有成員子類是不能繼承的)
- 子類方法訪問權限不能更低(public > 默認 > 私有)
Java中繼承的注意事項
- Java中類只支持單繼承,不支持多繼承
錯誤範例:class A extends B, C { }
- Java中類支持多層繼承多層繼承示例代碼:
-
package 包
- 包的概念包就是文件夾,用來管理類文件的
- 包的定義格式
package 包名; (多級包用.分開) 例如:package com.heima.demo;
- 帶包編譯&帶包運行
帶包編譯:javac –d . 類名.java 例如:javac -d . com.heima.demo.HelloWorld.java
帶包運行:java 包名+類名
例如:java com.heima.demo.HelloWorld
-
修飾符
-
重載
注意:方法的重載必須在一個類中,方法名、參數列表相同返回值不同不是方法重載(方法重載與返回值無關),方法重載返回值類型可以不相同
-
final
fianl關鍵字的作用
final代表最終的意思,可以修飾成員方法,成員變量,類 final修飾類、方法、變量的效果
fianl修飾類:該類不能被繼承(不能有子類,但是可以有父類) final修飾方法:該方法不能被重寫
final修飾變量:表明該變量是一個常量,不能再次賦值
final修飾的變量是基本類型時,指的是基本類型的數據值不能發生改變
final修飾的變量是引用類型時,指的是引用類型的地址值不能發生改變,但是地址裏面的內容是可以發生改變的
final StringBuilder str = new StringBuilder("qwe");
System.out.println(str); //qwe
str.append("asd");
System.out.println(str); //qweasd
final Children ch = new Children();
ch.name="test";
System.out.println(ch.name); //test
ch.name="李淳罡";
System.out.println(ch.name); //李淳罡
-
static
static關鍵字是靜態的意思,可以修飾【成員方法】,【成員變量】 static修飾的特點
- 被類的所有對象共享,這也是我們判斷是否使用靜態關鍵字的條件
- 可以通過類名調用當然,也可以通過對象名調用【推薦使用類名調用】
static的訪問特點
非靜態的成員方法
能訪問靜態的成員變量
能訪問非靜態的成員變量能訪問靜態的成員方法
能訪問非靜態的成員方法靜態的成員方法
能訪問靜態的成員變量能訪問靜態的成員方法總結成一句話就是:
靜態成員方法只能訪問靜態成員
-
多態
- 什麼是多態 同一個對象,在不同時刻表現出來的不同形態多態的前提
- 要有繼承或實現關係要有方法的重寫
- 要有父類引用指向子類對象
多態中的成員訪問特點
成員變量 編譯看父類,運行看父類
成員方法 編譯看父類,運行看子類
public class Father{
int age = 30;
public void test1(){
System.out.println("父類test1");
}
}
public class Children extends Father {
int age = 20;
@Override
public void test1(){
System.out.println("子類test1");
}
}
public class Test {
public static void main(String[] args) {
Father fa = new Children();
System.out.println(fa.age);
fa.test1();
}
}
//-------------------result-----------------------------
30
子類test1
-
多態的好處和弊端
- 好處
提高程序的擴展性。定義方法時候,使用父類型作爲參數,在使用的時候,使用具體的子類型參與操作
- 弊端
不能使用子類的特有成員
-
多態中的轉型
向上轉型:
從子到父:父類的引用指向子類對象
向下轉型:
父類引用轉爲子類對象
package com.polym;
public class Animal {
public void eat(){
System.out.println("動物喫東西");
}
}
package com.polym;
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("貓喫東西");
}
public void catchMouse(){
System.out.println("貓抓老鼠");
}
}
package com.polym;
public class Test {
public static void main(String[] args) {
Animal ani = new Cat(); //向上轉型
ani.eat();
//ani.catchMouse(); //報錯
Cat cat = (Cat)ani; //向下轉型
cat.catchMouse(); //調用貓類的特有方法
}
}
//--------------------------result---------------------------------
貓喫東西
貓抓老鼠
-
抽象類的概述
當我們在做子類共性功能抽取時,有些方法在父類中並沒有具體的體現,這個時候就需要抽象類了! 在Java中,一個沒有方法體的方法應該定義爲抽象方法,而類中如果有抽象方法,該類必須定義爲抽象類!
抽象類和抽象方法必須使用 abstract 關鍵字修飾
- 抽象類中不一定有抽象方法,有抽象方法的類一定是抽象類
- 抽象類不能實例化
抽象類如何實例化呢?參照多態的方式,通過子類對象實例化,這叫抽象類多態
3.抽象類的子類: 要麼重寫抽象類中的所有抽象方法 要麼是抽象類
-
抽象類的成員特點
-
接口
接口就是一種公共的規範標準,只要符合規範標準,大家都可以通用。
Java中的接口更多的體現在對行爲的抽象!
-
接口的成員特點
成員特點
默認修飾符: public static final
所以接口成員變量只能是常量
灰色的代表默認修飾符,兩行代碼等價
構造方法
接口沒有構造方法,因爲接口主要是對行爲進行抽象的,是沒有具體存在的
一個類如果沒有父類,默認繼承自Object類
public class runIm extends Object implements run {
public runIm() {
super(); //此處的super()訪問的是Object類的構造方法
}
@Override
public void runTest() {
}
成員方法
默認修飾符:public abstract
所以接口的成員方法只能是抽象方法
類與類的關係
繼承關係,只能單繼承,但是可以多層繼承 類與接口的關係
實現關係,可以單實現,也可以多實現,還可以在繼承一個類的同時實現多個接口
接口與接口的關係
繼承關係,可以單繼承,也可以多繼承
-
接口組成更新
-
接口中默認方法
public interface ShowTest {
void show();
//實現類不要求強制重寫
default void show2(){
System.out.println("接口默認方法show3");
}
}
public class ShowImplements implements ShowTest {
@Override
public void show(){
System.out.println("ShowImplements實現的show方法");
}
//接口默認方法可重寫也可不重寫
@Override
public void show2() {
System.out.println("ShowImplements實現的show2方法");
}
}
public static void main(String[] args) {
ShowTest st = new ShowImplements();
st.show();
st.show2();
}
/*
ShowImplements實現的show方法
ShowImplements實現的show2方法
*/
-
接口中靜態方法
注意:具體類的靜態方法可以通過類名或者對象名調用,但是接口的靜態方法只能通過接口名稱調用
public interface ShowTest {
void show();
static void show2(){
System.out.println("接口靜態方法show2");
}
}
public class ShowImplements implements ShowTest {
@Override
public void show(){
System.out.println("ShowImplements實現的show方法");
}
}
public static void main(String[] args) {
ShowTest st = new ShowImplements();
st.show();
//st.show2(); //報錯
//接口的靜態方法只能通過接口名調用
ShowTest.show2();
}
/*
ShowImplements實現的show方法
接口靜態方法show2
*/
-
接口中私有方法
public interface Inter {
default void show1() {
System.out.println("show1開始執行");
// System.out.println("初級工程師");
// System.out.println("中級工程師");
// System.out.println("高級工程師");
// show(); //非靜態方法可以調用非靜態方法也可以調用靜態方法
method(); //非靜態方法可以調用非靜態方法也可以調用靜態方法
System.out.println("show1結束執行");
}
default void show2() {
System.out.println("show2開始執行");
// System.out.println("初級工程師");
// System.out.println("中級工程師");
// System.out.println("高級工程師");
// show(); //非靜態方法可以調用非靜態方法也可以調用靜態方法
method(); //非靜態方法可以調用非靜態方法也可以調用靜態方法
System.out.println("show2結束執行");
}
private void show() {
System.out.println("初級工程師");
System.out.println("中級工程師");
System.out.println("高級工程師");
}
static void method1() {
System.out.println("method1開始執行");
// System.out.println("初級工程師");
// System.out.println("中級工程師");
// System.out.println("高級工程師");
// show();
method();
System.out.println("method1結束執行");
}
static void method2() {
System.out.println("method2開始執行");
// System.out.println("初級工程師");
// System.out.println("中級工程師");
// System.out.println("高級工程師");
method();
System.out.println("method2結束執行");
}
private static void method() {
System.out.println("初級工程師");
System.out.println("中級工程師");
System.out.println("高級工程師");
}
}
-
內部類
內部類概念:在一個類中定義一個類
訪問特點:
- 內部類可以直接訪問外部類的成員,包括私有
- 外部類要訪問內部類的成員,必須創建對象
成員內部類
私有成員內部類,外界可以訪問可以使用外部類對象調用本類方法沒方法中再訪問私有內部類
局部內部類
匿名內部類
匿名內部類的前提:存在一個類或者接口,這裏的類可以是具體類也可以是抽象類
格式:
public class Anonymous {
public void method(){
//匿名內部類
Inter i = new Inter(){
@Override
public void show() {
System.out.println("匿名內部類");
}
};
i.show();
}
}
匿名內部類的本質:是一個繼承了該類或者實現了該接口的子類匿名對象
-
Math(應用)
- Math類概述:Math 包含執行基本數字運算的方法
- Math中方法的調用方式:Math類中無構造方法,但內部的方法都是靜態的,則可以通過 類名.進行調用
- Math類的常用方法
方法名 方法名 |
說明 |
public static int abs(int a) |
返回參數的絕對值 |
public static double ceil(double a) |
返回大於或等於參數的最小double值,等於一個整數 |
public static double floor(double a) |
返回小於或等於參數的最大double值,等於一個整數 |
public static int round(float a) |
按照四捨五入返回最接近參數的int |
public static int max(int a,int b) |
返回兩個int值中的較大值 |
public static int min(int a,int b) |
返回兩個int值中的較小值 |
public static double pow (double a,double b) |
返回a的b次冪的值 |
public static double random() |
返回值爲double的正值,[0.0,1.0) |
獲取0-99的隨機整數
double random = Math.random();
System.out.println(random);
int ran = (int)(random*100);
System.out.println(ran);
-
System(應用)
System類的常用方法
方法名 |
說明 |
public static void exit(int status) |
終止當前運行的 Java 程序,非零表示異常終止 |
public static long currentTimeMillis() |
返回當前時間(以毫秒爲單位) |
計算程序耗時
long start_time = System.currentTimeMillis();
for(int i=0;i<10000;i++){
System.out.println(i);
}
long end_time = System.currentTimeMillis();
System.out.println("共耗時:"+(end_time-start_time)+"毫秒");
-
Object類(應用)
Object類概述:Object 是類層次結構的根,每個類都可以將 Object 作爲超類。所有類都直接或者間接的繼承自該類,換句話說,該類所具備的方法,所有類都會有一份查看方法源碼的方式
-
object toString方法
重寫快捷鍵: Alt + Insert 選擇toString
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
- public String toString()
- 返回對象的字符串表示形式。 一般來說,
toString
方法返回一個“toString
代表”這個對象的字符串。 結果應該是一個簡明扼要的表達,容易讓人閱讀。 建議所有子類覆蓋此方法。該
toString
類方法Object
返回一個由類的名稱,其中所述對象是其實例,該符號字符`的字符串@
”,並且對象的哈希碼的無符號的十六進制表示。 換句話說,這個方法返回一個等於下列值的字符串:getClass().getName() + '@' + Integer.toHexString(hashCode())
- 返回對象的字符串表示形式。 一般來說,
StudentNo stuNo = new StudentNo(1,"李淳風",25);
System.out.println(stuNo);
//重寫toString方法
Student stu = new Student(1,"李淳風",25);
System.out.println(stu);
/* public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
*/
}
package com.ObjectStudy;
public class Student {
private int id;
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
...
}
-
Object類的equals方法
重寫快捷鍵: Alt + Insert 選擇equals 刪除 hashCode
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (id != student.id) return false;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
equals方法的作用
用於對象之間的比較,返回true和false的結果舉例:s1.equals(s2); s1和s2是兩個對象
重寫equals方法的場景
不希望比較對象的地址值,想要結合對象屬性進行比較的時候。
重寫equals方法的方式
-
冒泡排序原理
冒泡排序概述:
一種排序的方式,對要進行排序的數據中相鄰的數據進行兩兩比較,將較大的數據放在後面,依次對所有的數據進行操作,直至所有數據按要求完成排序如果有n個數據進行排序,總共需要比較n-1次,每一次比較完畢,下一次的比較就會少一個數據參與
數組冒泡排序
int[] arr = new int[10];
//生成隨機長度爲10的數組
for(int i=0; i< 10;i++){
int j = (int)(Math.random()*100);
arr[i] = j;
}
System.out.println(Arrays.toString(arr));
//冒泡排序
for(int i =1;i<arr.length;i++) {
for(int j=0;j<arr.length-i;j++) {
if(arr[j]>arr[j+1]) {
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
//------------------------result------------------------
[75, 10, 7, 71, 47, 82, 87, 61, 23, 31]
[7, 10, 23, 31, 47, 61, 71, 75, 82, 87]
列表冒泡排序
ArrayList<Integer> arr = new ArrayList<Integer>();
//生成隨機長度爲10的列表
for(int i=0; i< 10;i++){
int j = (int)(Math.random()*100);
arr.add(j);
}
System.out.println(arr);
//冒泡排序
for(int i=arr.size()-1;i>0;i--){
for(int j=0;j<i;j++){
if(arr.get(j) > arr.get(j+1)){
int temp = arr.get(j+1);
arr.set(j+1, arr.get(j));
arr.set(j, temp);
}
}
}
System.out.println(arr);
//----------------result--------------
[47, 29, 83, 61, 54, 34, 6, 1, 35, 43]
[1, 6, 29, 34, 35, 43, 47, 54, 61, 83]
-
Arrays(應用)
Arrays的常用方法
方法名 |
說明 |
public static String toString(int[] a) |
返回指定數組的內容的字符串表示形式 |
public static void sort(int[] a) |
按照數字順序排列指定的數組 |
-
工具類設計思想
- 構造方法用 private 修飾 (防止外界創建對象)
- 成員用 public static 修飾 (可以直接使用類名調用)
-
包裝類
基本類型包裝類
將基本數據類型封裝成對象的好處在於可以在對象中定義更多的功能方法操作該數據
常用的操作之一:用於基本數據類型與字符串之間的轉換 基本類型對應的包裝類
基本數據類型 |
包裝類 |
byte |
Byte |
short |
Short |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
char |
Character |
boolean |
Boolean |
-
Integer類
Integer類概述:包裝一個對象中的原始類型 int 的值
Integer類構造方法
方法名 |
說明 |
public Integer(int value) |
根據 int 值創建 Integer 對象(過時) |
public Integer(String s) |
根據 String 值創建 Integer 對象(過時) |
public static Integer valueOf(int i) |
返回表示指定的 int 值的 Integer 實例 |
public static Integer valueOf(String s) |
返回一個保存指定值的 Integer 對象 String |
-
int和String類型的相互轉換
-
自動拆箱和自動裝箱
自動裝箱:把基本數據類型轉換爲對應的包裝類類型
自動拆箱:把包裝類類型轉換爲對應的基本數據類型
//裝箱:把基本數據類型轉換爲對應的包裝類類型
Integer i = Integer.valueOf(100);
//自動裝箱
Integer ii = 100; //底層依然是: Integer.valueOf(100);
-
時間日期類
Date類
Date 代表了一個特定的時間,精確到毫秒
Date類構造方法
方法名 |
說明 |
public Date() |
分配一個 Date對象,並初始化,以便它代表它被分配的時間,精確到毫秒 |
public Date(long date) |
分配一個 Date對象,並將其初始化爲表示從標準基準時間起指定的毫秒數 |
Date類常用方法
方法名 |
說明 |
public long getTime() |
獲取的是日期對象從1970年1月1日 00:00:00到現在的毫秒值 |
public void setTime(long time) |
設置時間,給的是毫秒值 |
-
SimpleDateFormat類
SimpleDateFormat是一個具體的類,用於以區域設置敏感的方式格式化和解析日期。
SimpleDateFormat類構造方法
方法名 |
說明 |
public SimpleDateFormat() |
構造一個SimpleDateFormat,使用默認模式和日期格式 |
public SimpleDateFormat(String pattern) |
構造一個SimpleDateFormat使用給定的模式和默認的日期格式 |
public static void main(String[] args) throws ParseException {
//格式化
Date time = new Date();
SimpleDateFormat tmFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String currentIime = tmFormat.format(time);
System.out.println(currentIime);
System.out.println("------------------------");
//解析
String strTime = "2019年12月15日 16:11:22";
SimpleDateFormat tmFormat2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date dd = tmFormat2.parse(strTime);
System.out.println(dd);
}
//-------------------------result----------
2019年10月20日 16:15:27
------------------------
Sun Dec 15 16:11:22 CST 2019
-
Calendar類
Calendar 爲特定瞬間與一組日曆字段之間的轉換提供了一些方法,併爲操作日曆字段提供了一些方法 Calendar 提供了一個類方法 getInstance 用於獲取這種類型的一般有用的對象。
該方法返回一個Calendar 對象。
其日曆字段已使用當前日期和時間初始化:Calendar rightNow = Calendar.getInstance();
Calendar類常用方法
方法名 |
說明 |
public int get(int field) |
返回給定日曆字段的值 |
public abstract void add(int field, int amount) |
根據日曆的規則,將指定的時間量添加或減去給定的日曆字段 |
public final void set(int year,int month,int date) |
設置當前日曆的年月日 |
public static void main(String[] args) throws ParseException {
Calendar nowCa = Calendar.getInstance();
System.out.println(nowCa);
int year = nowCa.get(Calendar.YEAR);
int month = nowCa.get(Calendar.MONTH) + 1; //月是從0開始的,要獲取當月需要加一
int date = nowCa.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");
//日曆的加減
//獲取5年後的前3天
nowCa.add(Calendar.YEAR, 5);
nowCa.add(Calendar.DATE, -3);
year = nowCa.get(Calendar.YEAR);
month = nowCa.get(Calendar.MONTH) + 1; //月是從0開始的,要獲取當月需要加一
date = nowCa.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");
System.out.println("----------------------");
//設置日曆值,設置日曆值:2025年5月20日
nowCa.set(2025,4,20);
year = nowCa.get(Calendar.YEAR);
month = nowCa.get(Calendar.MONTH) + 1; //月是從0開始的,要獲取當月需要加一,設置爲設置值
date = nowCa.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");
}
//--------------------------result----------------------
2019年10月20日
2024年10月17日
----------------------
2025年5月20日
-
二月天案例
獲取任意一年的二月有多少天
思路:先獲取該年的3月1日,往前推一天就是2月的最後一天也就是這月有多少天
public static void main(String[] args) throws ParseException {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("請輸入任意月份:");
int input = scan.nextInt();
Calendar nowCalendar = Calendar.getInstance();
//設置當前日曆值爲:輸入年3月1日(日曆值月份是從0開始)
nowCalendar.set(input, 2, 1);
//獲取前一天
nowCalendar.add(Calendar.DATE, -1);
int dateNumber = nowCalendar.get(Calendar.DATE);
System.out.println("該年2月共有:" + dateNumber + "天");
}
}
//-------------------------result-----------------------
請輸入任意月份:
2019
該年2月共有:28天
請輸入任意月份:
2020
該年2月共有:29天
-
異常
異常就是程序出現了不正常的情況
-
try-catch方式處理異常
try-catch-finally執行順序:先執行try語句,如果try語句中有return,則finally語句在try語句執行return之前執行,如果finally語句中有return則直接退出
public static void main(String[] args) throws IOException {
System.out.println(show());
}
public static int show(){
try {
System.out.println(1);
//製造異常
int index = "ab".getBytes()[3];
return 41;
}catch (Exception e){
System.out.println(e);
return 42;
}finally {
System.out.println(2);
//return 3;
}
}
/*
1
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 2
2
42
*/
public static void main(String[] args) throws ParseException {
System.out.println("開始");
String a = null;
try {
a.split("");//java.lang.NullPointerException
} catch (NullPointerException e) {
System.out.println("空指針異常:");
e.printStackTrace();
}
System.out.println("結束");
/*開始
空指針異常:
java.lang.NullPointerException
at com.Test.Test.main(Test.java:12)
結束*/
}
public static void main(String[] args) throws ParseException {
System.out.println("開始");
int[] arr = {1,2,3};
try {
int a = arr[3]; //java.lang.ArrayIndexOutOfBoundsException: 3
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("數組索引越界:");
e.printStackTrace();
}
System.out.println("結束");
/*開始
數組索引越界:
java.lang.ArrayIndexOutOfBoundsException: 3
at com.Test.Test.main(Test.java:12)
結束*/
}
-
Throwable成員方法
常用方法
方法名 |
說明 |
public String getMessage() |
返回此 throwable 的詳細消息字符串(返回錯誤原因) |
public String toString() |
返回此可拋出的簡短描述 |
public void printStackTrace() |
把異常的錯誤信息輸出在控制檯(打印錯誤信息最全,一般採用此方法) |
-
throws方式處理異常
-
編譯時異常和運行時異常的區別
-
自定義異常(應用)
throws 和throw的區別
public static void main(String[] args) {
int score = 105;
try {
ScoreTest.checkScore(score);
} catch (ScoreException e) {
e.printStackTrace();
}
}
public static void checkScore(int score) throws ScoreException {
if(score>=0 && score <=100){
System.out.println("分數正常");
}else{
throw new ScoreException("分數異常,給定分數不在0-100之間");
}
}
public class ScoreException extends Exception {
public ScoreException() {
}
public ScoreException(String message) {
super(message);
}
}
//--------------------------result-------------------------------
com.ThrowTest.ScoreException: 分數異常,給定分數不在0-100之間
at com.ThrowTest.ScoreTest.checkScore(ScoreTest.java:19)
at com.ThrowTest.ScoreTest.main(ScoreTest.java:9)