Java基礎總結之字節、數組、字符串、面向對象

一、字節(8個)
8bit = 1B或1byte
1024B = 1Kb


二、強制類型轉換順序及其大小順序
遵循向上轉換的規則
byte,short,char -> int -> long -> double

Byte    --  一個字節  2的1*8次方
Short   --  兩個字節  2的2*8次方
Int     --  四個字節  2的4*8次方
Long    --  八個字節  2的8*8次方
Char    --  兩個字節  2的2*8次方
Float   --  四個字節  2的4*8次方
Double  --  八個字節  2的8*8次方


注意事項byte,short,char相互之間不轉換,他們參與運算首先轉換爲int類型


notes:
null是給引用數據類型賦值用的

ASCLL對應的:
0 --> 48
9 -->  57
A --> 65
Z --> 90
a --> 97
z --> 122
三、方法重載
1.方法名一樣,參數不一樣 || 返回值不一樣(或的關係)2018.6.14 改爲跟返回值沒關係

四、數組 [] 
1.需要注意的事項
需要定義長度,創建對象
2.命名格式
數組:1。長度固定 2.同種數據類型元素
String [] arr = new String[3]  固定長度的數組
String [] arr = new String[]{"12ab","java","45Cd","Server78"}
String [] arr = {"12ab","java","45Cd","Server78"}

notes:
當數據確定時,建議用第三種,(靜態初始化)
當數據不確定時,建議用第一種(動態初始化)
根據索引訪問數組的元素

3.數組原理內存圖、

區域名稱    作用
寄存器 給CPU使用,和我們開發無關。
本地方法棧 JVM在使用操作系統功能的時候使用,和我們開發無關。
方法區 存儲可以運行的class文件。
堆內存 存儲對象或者數組,new來創建的,都存儲在堆內存。
方法棧 方法運行時使用的內存,比如main方法運行,進入方法棧中執行


此處應有一個數組內存圖
程序執行流程:
1.main方法進入方法棧執行
2.創建數組,jvm會在堆內存中開闢空間,存儲數組
3.數組內存中會有自己的內存地址,以十六進制表示
4.數組中有自己定義長度,不給初始化值則默認是0
5.jvm將數組的內存地址賦值給引用類型變量arr
6.變量arr保存的是數組內存中的地址,而不是一個具體具體是數值,因此稱爲引用數據類型.


五、字符串
1.  3種構造方法
String str = String("你好")
char arr[] = {'h','e','l','l'}

String str1 = new String(arr); //hello
String str2 = new String(arr,0,3) //hel

2. 以下兩種方式 對比其區別
方式1 String s = "hello";
方式2 String s = new String("hello")

情況1:常量池中有字符串常量"aaa"
通過方式1創建對象,程序運行時會在常量池中查找"aaa"字符串,將找到的"aaa"字符串地址賦值給s
通過方式2創建對象,無論常量池中有沒有"aaa"字符串 程序都會在堆內存中開闢一片新的空間來存放新對象

情況1:常量池中沒有字符串常量"aaa"
通過方式1創建對象,程序運行時會在常量池中查找"aaa"字符串,將找到的"aaa"字符串地址賦值給s

通過方式2創建對象,程序會在堆內存中開闢一片新空間存放新的對象,同時會將"aaa"字符存入常量池,相當於創建了2個對象

3.進行字符串比較時:
情況1:若是用 == 
(1)若是基本類型 則比較的是值是否相同
(2)若是引用類型 則比較地址是否相同

情況2:那咋比呢?
用equals進行比較
equals(String str) 比較的時內容
equalsIgnoreCase() 忽略大小寫比較內容
4.String str.方法
concat()  將指定字符串連接到字符串末尾
charAt() 返回指定索引處的char值
indexOf() 返回指定字符串 第一次出現的 索引值
substring(int beginIndex) 返回一個字符串,從beginIndex開始截取字符串到末尾並返回ndex開始截取字符串到末尾並返回
substring(int beinIndex,int endIndex) 返回一個字符串,從beginIndex開始到endIndex結束
toUpperCase() 將字符串轉換成 全部大寫
toLowerCAse() 將字符串轉換成 全部小寫

5.Math基本方法
Math.方法
abs  -->返回 絕對值
radom() 返回一個double的正值 大於等於0.0 小於1.0
ceil() 返回大於等於參數的最小的整數
floor() -->返回一個小於或者等於參數的最大的整數
round() -->返回最接近參數的long(相當於四捨五入方法)

六、面向對象
1.重寫 的理解
1.子類中出現與父類一樣的方法時,會出現覆蓋的操作
2.子類需要父類的功能,並且子類自己還有一些特定的內容,可以重寫父類的方法
3.注意事項:
a.子類覆蓋父類的方法,必須保證權限要大於等於父類的權限
b.子類與父類的方法聲明必須一樣:函數的返回值 函數名 參數列表一樣

2.抽象

1.抽象方法的特點
a.只有方法聲明沒有方法主體
b.只能存在抽象類中


2.什麼時候用抽象方法:
a.某個父類只知道子類應該有什麼方法,但是不知道子類是怎麼實現的
3.抽象類可以直接創建對象麼?爲什麼
不可以,因爲抽象類有抽象方法,new一個對象,調用抽象方法時無意義的
4.請問抽象類可以有構造方法嗎,構造方法在抽象類有意義嗎?
可以有 有意義 子類的構造方法可以調用抽象父類中的構造方法給成員變量進行賦值
5.抽象類一定時父類麼?
抽象類一定是個父類,因爲抽象類是不斷抽取共性需求而來的
6.抽象類中可以沒有抽象方法麼?
可以,可以不定義抽象方法,此時僅僅是不讓該類創建對象,用於某些特殊的需要
7.請問是先有抽象類還是先有子類?
設計時由具體抽取處抽象類,而開發階段則應該先定義抽象類,再根據不同需要由父類定義子類

notes:
1.抽象類中不一定有抽象方法,但是抽象方法的類必定是抽象類
2.抽象類的子類,必須重寫抽象父類中所有的抽象方法,否則,編譯無法通過而報錯,除非該子類也是抽象類



3.static關鍵字:
當static修飾成員變量時:
static關鍵字的使用,它可以用來修飾成員變量和成員方法,
被修飾的成員變量屬於類,而不是單單屬於某個對象,
也就是說被static修飾的成員變量既然屬於類,就可以不靠創建對象調用了,
該類的每個對象都可以共享同一個類變量的值,任何對象都可以更改該類變量的值,
但也可以通過不創建該類變量的情況下對改類變量進行操作。

當static修飾方法時:
建議使用類名調用,而不需要創建類對象,

notes:
~靜態方法可以直接訪問靜態類變量,和靜態方法
~靜態方法不能直接訪問普通成員變量和方法,反之成員方法可以直接訪問靜態類變量或靜態方法
~靜態方法中,不能直接使用this關鍵字

被static修飾的成員建議通過類名直接訪問,雖然可以通過對象名字訪問靜態成員,
原因既多個對象均屬於一個類,共享使用同一個靜態成員,但是不建議,會出現警告信息


4.靜態代碼塊
~是隨着類的加載而加載,且只加載一次。
~存儲在內存中特殊的區域(靜態區)所有可以直接被類名調用
~它優先與對象存在,所有,可以被所有對象共享


七、面向對象三大特徵
1.封裝
2.繼承
繼承:就是子類繼承父類的屬性和行爲,使得子類對象具有與父類相同的屬性、
相同的行爲。子類可以直接 訪問父類中的非私有的屬性和行爲。 

A.繼承之後對 成員變量 產生的影響:

a.當子類與父類變量不重名則沒有影響
b.當子類與父類變量重名時
會根據就近原則,優先使用子類的變量

notes:
怎麼避免這樣的情況:
可以根據 super.父類成員變量來訪問父類非私有成員變量
通常編碼時,我們遵循封裝的原則,使用private修飾成員變量,
那麼如何訪問父類的私有成員 變量呢?對!可以在父類中提供公共的getXxx方法
和setXxx方法
可以根據 this.父類成員變量來訪問當前成員變量

B.繼承之後對 成員方法 的影響:

a.當子類與父類方法不重名則沒有影響

b.當子類與父類方法重名時
這時的訪問是一種特殊情況,叫做方法重寫 (Override)。
方法重寫:
子類中出現與父類一模一樣的方法時(返回值類型,方法名和參數列表都相同),
會出現覆蓋效 果,也稱爲重寫或者複寫。聲明不變,重新實現。

notes:
1.子類必須保證權限大於或者等於父類權限
2.子類在進行覆蓋時,必須要保證,返回值類型,方法名,參數列表一樣

C.繼承之後對 構造方法 的影響:
構造方法是一致的,所以子類是無法繼承父類構造方法的
構造方法是初始化變量用的,在進行子類進行初始化的時候,默認會有一個super()來對父類進行初始化,父類初始化後才能給子類使用


3.多態
多態: 是指同一行爲,具有多個不同表現形式。 

1.前提也是重點:
a.繼承或者實現[二選一] 這是前提
b.方法重寫[意義體現:不重寫,無意義]
父類類型 變量名 = new 子類對象
變量名.方法名();
c.父類引用指向子類對象[格式體現]

當使用多態方式調用方法時,首先檢查父類中是否有該方法,
如果沒有,則編譯錯誤;如果有,執行的是子類重寫 後方法

2.引用類型轉換
多態的類型分爲向上轉型和向下轉型

向上轉型:
多態本身就是子類類型向父類類型轉換,默認執行,當一個父類類型指向一個子類類型時就是向上轉型

向下轉型:
父類類型向子類類型轉換的過程,這個過程時強制的

格式:
子類類型 變量名 = (子類類型) 父類變量名;
如:Cat c = (Cat) a;
爲啥要轉型:?
當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤。也就是說,不能調用子類擁 有,而父類沒有的方法。編譯都錯誤,更別說運行了。這也是多態給我們帶來的一點"小麻煩"。所以,想要調用子 類特有的方法,必須做向下轉型

想要調用子類特有方法,需要轉型

3.做類型校驗
public class Test{
public static void main(String[] args){
// 向上轉型
Animal a = new Cat();
a.eat();

// 向下轉型
if (a instanceof Cat){
c.catchMouse(); // 調用的是 Cat的catchMouse
}else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHose() // 調用的是 Dog的 watchHose
}
}
}
? ????


八、接口
是java中一個引用類型,是方法的集合,如果說類的內部封裝了成員變量,構造方法和成員方法,那麼接口的內部主要時封裝了方法,
包含了抽象方法(JDK7之前),默認方法和靜態方法(jdk8),私有方法(jdk9)

接口包含抽象方法:
abstract 來修飾 也可以省略,沒有方法體,該方法提供子類實現使用

接口包含抽象方法:
默認方法 使用 default 不可省略 供子類調用或者子類重寫
靜態方法 使用 static 修飾 供接口直接調用
私有方法 使用 private 修飾 供接口中的默認方法或者靜態方法調用

notes:
非抽象子類實現接口:
1.必須重寫接口中所有抽象方法
2.繼承了接口的默認方法,即可直接調用,也可以重寫
接口的靜態方法的使用:
只能使用接口名調用,不可以通過實現類的類名或者實現類的對象調用,
接口私有方法的使用:
私有方法:只有默認方法可以調用
私有靜態方法:默認方法和靜態方法可以調用

接口中,有多個抽象方法時,實現類必須重寫所有抽象方法。如果抽象方法有重名的,只需要重寫一次。代碼如 下:
接口中,有多個默認方法時,實現類都可繼承使用。如果默認方法有重名的,必須重寫一次
接口中,存在同名的靜態方法並不會衝突,原因是隻能通過各自接口名訪問靜態方法



子接口重寫默認方法時,default關鍵字可以保留。 
子類重寫默認方法時,default關鍵字不可以保留。

接口中,無法定義成員變量,但是可以定義常量,其值不可以改變,默認使用public static ?nal修飾。 
接口中,沒有構造方法,不能創建對象。 
接口中,沒有靜態代碼塊


notes:
數組和類作爲返回值時 返回一個地址,這個地址在數組中表示的是一個空間,在類裏面表示的是一個對象
接口作爲返回值時 返回一個地址,是一個接口的子對象


九、final 關鍵字

final: 不可改變。可以用於修飾類、方法和變量。 

類:被修飾的類,不能被繼承。但是可以繼承其他類 
方法:被修飾的方法,不能被重寫。 父類中方法沒有final 子類覆蓋後可以加final
變量:被修飾的變量,不能被重新賦值。

1.修飾變量
1.局部變量 -- 基本類型
基本類型的局部變量,被final修飾後,只能賦值一次,不能再更改

2.局部變量 -- 引用類型
引用類型的局部變量,被fianl修飾後,只能指向一個對象,表示地址不能再更改,但是不影響對象內部的成員變量賦值

3.成員變量
被final修飾的常量名稱,一般都有書寫規範,所有字母都大寫

2.請寫出final的特點及final可以修飾什麼
2.1 ?final修飾類不可以被繼承,但是可以繼承其他類。
2.2   final修飾的方法不可以被覆蓋,但父類中沒有被final修飾方法,子類覆蓋後可以加final。
2.3 ?final修飾的變量稱爲常量,這些變量只能賦值一次。
2.4 ?引用類型的變量值爲對象地址值,地址值不能更改,但是地址內的對象屬性值可以修改。
2.5 ?修飾成員變量,需要在創建對象前賦值,否則報錯。(當沒有顯式賦值時,多個構造方法的均需要爲其賦值。)
2.6   final關鍵字是一個修飾符,可以修飾類,方法,局部變量,成員變量
權限修飾符:
public protected default private  權限由大到小

沒有特殊考慮,建議這樣使用權限
1.成員變量使用private,隱藏細節
2.構造方法使用public,方便創建對象
3.成員方法使用public,方便調用對象

notes:
不加權限修飾,其訪問能力與default修飾符相同

內部類:
1.定義:
將一個類A定義在另一個類B裏面,裏面的那個類A就稱爲內部類,B則稱爲外部類。 

2.成員內部類 :定義在類中方法外的類
class 外部類 {
class 內部類{

}

3.在描述事物時,若一個事物內部還包含其他事物,就可以使用內部類這種結構。比如,汽車類 Car 中包含發動機 類 Engine ,這時, Engine 就可以使用內部類來描述,定義在成員位置
4.內部類特點:
內部類可以直接訪問外部類的成員,包括私有成員。 
外部類要訪問內部類的成員,必須要建立內部類的對象

格式:
public class InnerDemo{
// 創建外部類對象
Person p = new Person();

// 創建內部類對象
Heart heart = p.new Heart();

//調用內部類方法
heart.jump();

//調用外部類方法
p.setLive(false)

//調用內部類方法
heart.jump()
}

notes:
內部類仍然是一個獨立的類,在編譯之後會內部類會被編譯成獨立的.class文件,但是前面冠以外部類的類名 和$符號 。
比如,Person$Heart.class 

4.匿名內部類:
是內部類的簡化寫法.他的本質時一個帶具體實現的父類或者父接口的匿名子類對象
開發中,最常用到內部類.以接口舉例,當你使用一個接口時,需要做以下4個步驟
1. 定義子類 
2. 重寫接口中的方法 
3. 創建子類對象 
4. 調用重寫後的方法

在使用匿名內部類時的前提:
匿名內部類必須繼承一個父類或者實現一個父接口

格式:
new 父類名或者接口名(){
@Override
public void method(){
// 方法體
}
}

創建匿名內部類,並調用;
public class InnerDemo {
public static void main(String[] args) {
/*
1.等號右邊:是匿名內部類,定義並創建該接口的子類對象
2.等號左邊:是多態賦值,接口類型引用指向子類對象
*/
FlyAble f = new FlyAble(){
@Override
public void fly() {
System.out.println("︿( ̄︶ ̄)︿");
}
};


f.fly();
}
}


通常在方法的形式參數是接口或者抽象類時,也可以將匿名內部類作爲參數傳遞。代碼如下


public class InnerDemo1 {
public static void main(String[] args) {
FlyAble f = new FlyAble(){
public void fly() {
System.out.println("︿( ̄︶ ̄)︿");
}
};


showFly(f);
}
    
public static void showFly(FlyAble f){
f.fly();
}
}

可以將上述步驟進行轉換成更簡單的一步:

public class InnerDemo3 {
    public static void main(String[] args) {
        showFly(new FlyAble(){
            public void fly() {
                System.out.println("︿( ̄︶ ̄)︿");
            }
        });
    }


    public static void showFly(FlyAble f){
        f.fly();
    }
}


5.引用類型用法總結


















發佈了29 篇原創文章 · 獲贊 0 · 訪問量 8972
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章