最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

來杯JAVA冷靜一下_05面向?qū)ο骭06異常_230809

2023-08-10 17:54 作者:Biehmltym  | 我要投稿

# 來杯JAVA冷靜一下_05面向?qū)ο骭06異常_230809

面向?qū)ο?br>

### 1.初識(shí)面向?qū)ο?/p>

#### 面向過程思想

步驟清晰簡單,第一步做什么,第二步做什么…

面對(duì)過程適合處理一些較為簡單的問題。

#### 面向?qū)ο笏枷?/p>

物以類聚,分類的思維模式,思考問題首先會(huì)解決問題需要哪些分類,然后對(duì)這些分類進(jìn)行單獨(dú)思考。最后,才對(duì)某個(gè)分類下的細(xì)節(jié)進(jìn)行面向過程的思索。

面向?qū)ο筮m合處理復(fù)雜的問題,適合處理需要多人協(xié)作的問題!

對(duì)于描述復(fù)雜的事物,為了從宏觀上把握、從整體上合理分析,我們需要使用面向?qū)ο蟮乃悸穪矸治稣麄€(gè)系統(tǒng)。但是,具體到微觀操作,仍然需要面向過程的思路去處理。

面向?qū)ο缶幊蹋?Object- Oriented Programming,OOP)

### 面向?qū)ο缶幊痰谋举|(zhì)就是:

### -以類的方式組織代碼,

### -以對(duì)象的組織(封裝)數(shù)據(jù)。

#### 三大特征:

##### 繼承

##### 封裝

##### 多態(tài)

- 從認(rèn)識(shí)論角度考慮是先有對(duì)象后有類。對(duì)象,是具體的事物。

- 類,是抽象的,是對(duì)對(duì)象的抽象。

- 從代碼運(yùn)行角度考慮是先有類后有對(duì)象。類是對(duì)象的模板。

-?

### 2.方法回顧和加深 屬性+方法=類

對(duì)于描述復(fù)雜的事物,為了從宏觀上把握、從整體上合理分析,我們需要使用面向?qū)ο髞矸治稣麄€(gè)系統(tǒng)。但是,具體到微觀操作,讓然需要面向過程的思路去處理。

面向?qū)ο蟊举|(zhì)就是:以類的方式組織代碼,以對(duì)象的組織(封裝)數(shù)據(jù)。

從認(rèn)識(shí)論角度考慮是先有對(duì)象后有類

三大特性:封裝,繼承,多態(tài)。抽象

回顧方法的定義以及調(diào)用

定義


main方法

#### 1 方法的定義


1. 修飾符? ?public 公共類 private 私有類

2. 返回值類型

break:跳出 switch,結(jié)束循環(huán)和 return的區(qū)別。

3. 方法名:注意規(guī)范就OK,見名知意

參數(shù)列表:(參數(shù)類型,參數(shù)名) …

異常拋出:疑問,參考下文!


```java


//main方法

public static void main(String[] args){}

/*

修飾符 返回值類型 方法名(...){

//方法體

return 返回值;

}

*/

public String sayHello(){

? ? return "hello world";

}

public void print(){

? ? return;

}

public int max(int a,int b){

? ? return a>b ?a:b;

}


```

break:跳出switch循環(huán),結(jié)束循環(huán)。continue:結(jié)束依次循環(huán)。return:方法結(jié)束,返回類型和返回值相同。






```java

public class Demo01 {

? ? // main方法

? ? public static void main(String[] args) {


? ? }


? ? /*

? ? 修飾符 返回值類型 方法名(...){

? ? ? ? // 方法體

? ? ? ? return 返回值;

? ? }

? ? ?*/

? ? public String sayHello(){

? ? ? ? return "hello,world!";

? ? }


? ? public int max(int a,int b){

? ? ? ? return a>b ? a : b; // 三元運(yùn)算符

? ? }


? ? // 數(shù)組下標(biāo)越界:Arrayindexoutofbounds

? ? public void readFile(String file) throws IOException{


? ? }

}

```


### 3 方法的調(diào)用



#### 1 靜態(tài)方法?

? public static void a(){

b}//和類一起加載的

```java


public class Demo01 {

? ? public static void main(String[] args) {

? ? ? ? Student.main();

? ? }

}





//==============另一個(gè)文件?



//1 靜態(tài)方法?

public class Student {

? ? public static void main() {

? ? ? ? System.out.println("學(xué)生說話。。。");

? ? }


}



```



#### 2 非靜態(tài)方法?

public void b() {

}

//類實(shí)例化之后才存在??

```java

public class Student {

? ? public void main() {//去掉static

? ? ? ? System.out.println("學(xué)生hh說話。。。");

? ? }


}

//=======================

public class Demo01 {

? ? public static void main(String[] args) {

? ? ? ? //? Student.main();?

? ? ? ? //? 去掉static后 無法直接通過類名調(diào)用方法名

? ? ? ? //只能通過實(shí)例化

? ? ? ? Student studnet = new Student();

? ? ? ? studnet.main();

? ? }

}

```



#### 3 形參和實(shí)參


```java

public static void say(){

? ? system.out.print("1111");

}//可直接通過方法名調(diào)用,和類一起加載。

非靜態(tài)方法

public void say(){

? ? System.out.print("1111");

}

//調(diào)用

Student student = new Student();//實(shí)例化這個(gè)類new,對(duì)象類型 對(duì)象名=對(duì)象值;

student.say();

形參

public static int add(int a,int b){//int a,int b,形參

return a+b;? ??

}

實(shí)參

public static void main(String[] args){

? ? int add = Demo03.add(1,3);//1,3:實(shí)參

? ? System.out.println(add);

}

```

#### 4? java 都是值傳遞


一句話:對(duì)于**基本數(shù)據(jù)類型**來說,給形參傳遞的是實(shí)參值的副本,而對(duì)于引用數(shù)據(jù)類型來說,傳遞的則是地址的副本。但由于地址的副本和原來的相似,因此傳遞過去后的形參也指向同一個(gè)內(nèi)存空間中。

就是復(fù)制了一份給形參,自身不變

形參的有效范圍只在當(dāng)前方法內(nèi),輸出的值跟下面的a完全沒有任何關(guān)系



```java

//值傳遞

public class Demo04{

? ?public static void main(String[] args){

? ? ? ?int a=1;

? ? ? ?System.out.println(a);

? ? ? ?

? ? ? ?Demo04.change(a); //返回值為空? 運(yùn)行完,啥也沒有?

? ? ? ?System.out.println(a);

? ?}

? ??

? ? //返回值為空? 運(yùn)行完,啥也沒有?

? ? public static void change(int a){//a傳進(jìn)去1?

? ? ? ? a=10;//a= 1 ,將10 賦值給a,a=10;

? ? }

}

a=10,返回值為空,a的值還為1。

```

#### 5 引用傳遞


```java

//引用傳遞:對(duì)象,本質(zhì)還是值傳遞

public class Demo05{

? ? public static void main(String[] args){

? ? ? ? Person person = new Person();

? ? ? ??

? ? ? ? System.out.println(person.name);//null

? ? ? ??

? ? ? ? Demo05.change(person);

? ? ? ??

? ? ? ? System.out.println(person,name);//test

? ? }

? ? public static void change(Person person){

? ? ? ? //person是一個(gè)對(duì)象:指向的--->Person person=new Person();這是一個(gè)具體的人,可以改變屬性

? ? ? ? person.name = "test";

? ? };

}



//定義了一個(gè)Person類,有一個(gè)屬性:name

class Person{

? ? String name;//null

}



```




- 基本類型作為參數(shù)傳遞時(shí),是傳遞值的拷貝,無論你怎么改變這個(gè)拷貝,原值是不會(huì)改變的

- 對(duì)象作為參數(shù)傳遞時(shí),是對(duì)象在內(nèi)存中的地址拷貝一份給了參數(shù)

類和對(duì)象的關(guān)系

類是一種抽向的數(shù)據(jù)類型,它是對(duì)某一類事物整體描述/定義,但是并不能代表某一個(gè)具體的事物

對(duì)象是抽象概念的具體實(shí)例


#### 6 this關(guān)鍵字



#### 學(xué)程序好? 對(duì)世界進(jìn)行更好的建模?



### 4 類和對(duì)象的創(chuàng)建?

對(duì)象的創(chuàng)建分析

類是一種抽象的數(shù)據(jù)類型它是對(duì)某一類事物整體描述/定義但是并不能代表某一個(gè)具體的事物。

使用new關(guān)鍵字創(chuàng)建對(duì)象。

使用new關(guān)鍵字創(chuàng)建的時(shí)候,除了分配內(nèi)存空間之外,還會(huì)給刨建好的對(duì)象進(jìn)行默認(rèn)的初始化以及對(duì)類中構(gòu)造器的調(diào)用。



#### 創(chuàng)建和初始化對(duì)象


使用new關(guān)鍵字創(chuàng)建的時(shí)候,除了分配內(nèi)存空間之外,還會(huì)給創(chuàng)建好的對(duì)象進(jìn)行默認(rèn)的初始化以及類中構(gòu)造器的使用

1595485938430


一個(gè)類即使什么都不寫,它也會(huì)存在一個(gè)方法



```java

//學(xué)生類 以類的方式組織代碼?

public class Student {

//1 屬性 :字段? 不賦值 。

? ? String name;

? ? int age;

//2 方法?

? ? public void study() {

? ? ? ? System.out.println(

? ? ? ? ? ? ? ? this.name + "在學(xué)習(xí)"

? ? ? ? );

? ? }



}

```



```java


package com.zhangyy.opp;



//引用傳遞:對(duì)象,本質(zhì)還是值傳遞

public class Demo05 {

? ? public static void main(String[] args) {

? ? ? ? //類:抽象的 示例化

? ? ? ? //類:抽象的,實(shí)例化

? ? ? ? // 類實(shí)例化后會(huì)返回一個(gè)自己的對(duì)象!

? ? ? ? // student對(duì)象就是一個(gè)student類的具體實(shí)例!

Student xiaoming=new Student();

Student xh =new Student();

xiaoming.name = "小明";

? ? ? ? xiaoming.age=23;

? ? ? ? System.out.println(xiaoming.name);

? ? ? ? System.out.println(xiaoming.age);

? ? ? ? System.out.println(xh.name);

? ? ? ? System.out.println(xh.age);


? ? }


? ? ;

}



/*

小明

23

null

0


*/


```





```java


//引用傳遞:對(duì)象,本質(zhì)還是值傳遞

public class Demo05 {

? ? public static void main(String[] args) {

? ? ? ? //類:抽象的 示例化

? ? ? ? //類:抽象的,實(shí)例化

? ? ? ? // 類實(shí)例化后會(huì)返回一個(gè)自己的對(duì)象!

? ? ? ? // student對(duì)象就是一個(gè)student類的具體實(shí)例!

Student xiaoming=new Student();

Student xh =new Student();

xiaoming.name = "小明";

? ? ? ? xiaoming.age=18;

? ? ? ? System.out.println(xiaoming.name);

? ? ? ? System.out.println(xiaoming.age);

? ? ? ? System.out.println(xh.name);

? ? ? ? System.out.println(xh.age);


? ? }


? ? ;

}




```





### 5 構(gòu)造器

#### 構(gòu)造器:


```java

//Person.class

public class Person {


}



```



#### Person.class默認(rèn)無參構(gòu)造方法

```java

//Person.class默認(rèn) 無參構(gòu)造 方法


//

// Source code recreated from a .class file by IntelliJ IDEA

// (powered by FernFlower decompiler)

//


package com.zhangyy.opp;


public class Person {

? ? public Person() {

? ? }

}


```



#### 類中的構(gòu)造器也稱為構(gòu)造方法,是在進(jìn)行創(chuàng)建對(duì)象的時(shí)候必須要調(diào)用的。

#### 并且構(gòu)造器有以下倆個(gè)特點(diǎn):

//一個(gè)類即使什么都不寫,它也會(huì)存在一個(gè)方法

//顯示的定義構(gòu)造器

##### 1.必須和類的名字相同;


##### 2.必須沒有返回類型也不能寫void。


#### 構(gòu)造器: Command + N 方法的重載

快捷鍵 Command + N 打開Generate 操作菜單; 選擇Constructor,然后根據(jù)需要選擇相應(yīng)的構(gòu)造函數(shù)參數(shù); 點(diǎn)擊OK,即可生成相應(yīng)的構(gòu)造函數(shù)。

##### 1.和類名相同

##### 2.沒有返回值類型,也不能寫void

#### 作用:

##### 1.new本質(zhì)在調(diào)用構(gòu)造方法,默認(rèn)無參構(gòu)造方法;

##### 2.初始化對(duì)象的值。

#### 有參構(gòu)造與無參構(gòu)造

#### 注意:定義有參構(gòu)造之后,如果想使用無參構(gòu)造,顯示的定義一個(gè)無參構(gòu)造。

構(gòu)造器是無參構(gòu)造,方法也可以無參構(gòu)造

顯示定義無藏構(gòu)造:

//定義有參構(gòu)造器后,就會(huì)把系統(tǒng)默認(rèn)的無參構(gòu)造器給覆蓋掉了。如果想使用無參構(gòu)造器,那就得自己寫出來,即顯示的定義無參構(gòu)造器。


定義有參構(gòu)造器,它會(huì)覆蓋無參構(gòu)造器,如果你想要它還存在,那么就自己定義出來。

方法重載:有參無參都寫上,有參數(shù)就走有參,無參數(shù)就走無參,出來的是定義 的值

![](media/16913989124163/16915665070339.jpg)


```java

public class Person {

? ? String name;

//? ? public Person(){

//

//? ? ? ? this.name="雪之下雪乃";

//? ? }

? ? public? Person( String name){

? ? ? ? this.name = name;

? ? }


}

```

```java

public class Demo01 {

? ? public static void main(String[] args) {

Person person? ?= new Person("雪之下");


? ? ? ? System.out.println(person.name);

? ? }

}

//雪之下


```


#### A 未使用構(gòu)造器?

```java

public class Person {

? ? String name;


}

```

```java

public class Demo01 {

? ? public static void main(String[] args) {

Person person? ?= new Person();


? ? ? ? System.out.println(person.name);

? ? }

}

//null

```


#### B 使用構(gòu)造器?

//一個(gè)類即使什么都不寫,它也會(huì)存在一個(gè)方法

//顯示的定義構(gòu)造器

//實(shí)例化初始值

//1。使new關(guān)鍵字,本質(zhì)是在調(diào)用構(gòu)造器

```java

public class Person {

? ? String name;

? ? public Person(){


? ? ? ? this.name="雪之下雪乃";

? ? }

```




```java

public class Demo01 {

? ? public static void main(String[] args) {

Person person? ?= new Person();


? ? ? ? System.out.println(person.name);

? ? }

}

//雪之下雪乃


```


![](media/16913989124163/16915653541950.jpg)


### 6 內(nèi)存分析


![](media/16913989124163/16915684905993.jpg)




![](media/16913989124163/16915680357718.jpg)





沒有static時(shí),b調(diào)用的是對(duì)象的方法,而b是用A類new的,即b是A new出來的對(duì)象,因此調(diào)用了A的方法


### 7 小結(jié)類與對(duì)象

#### 1.類與對(duì)象


###### ?類是一個(gè)模板:抽象,對(duì)象是一個(gè)具體的實(shí)例


#### 2.方法


###### ?定義,通用


#### 3.對(duì)應(yīng)的引用


###### ?引用類型:基本類型(8)


###### ?對(duì)象是通過引用來操作的:棧--->堆(地址)


#### 4.屬性:字段Field? ? 成員變量


###### ?默認(rèn)初始化:


###### ?數(shù)字:0? ? 0.0


###### ?char:u0000


###### ?boolean:false


###### ?引用類型(String等):null


###### ?修飾符 屬性類型 屬性名=屬性值;

(方法省略 不要死循環(huán))


#### 5.對(duì)象的創(chuàng)建和使用


- 必須使用new關(guān)鍵字創(chuàng)建對(duì)象, 構(gòu)造器Person xiaoming=new Perosn();

- 對(duì)象的屬性 xiaoming.name

- 對(duì)象的方法 xiaoming.sleep()


#### 6.類


###### ?靜態(tài)的屬性 屬性

###### ?動(dòng)態(tài)的行為 方法


***

***

***


> # 面向?qū)ο笕筇匦裕悍庋b 繼承 多態(tài)

### 8 封裝 屬性私有,get/set 高內(nèi)聚低耦合

**主要是針對(duì)類的屬性進(jìn)行封裝**


該露的露,該藏的藏 類比ATM機(jī)

我們程序設(shè)計(jì)要追求**”高內(nèi)聚,低耦合“**。高內(nèi)聚就是類的內(nèi)部數(shù)據(jù)細(xì)節(jié)由自己完成,不允許外部干涉;低耦合:僅暴露少量的方法給外部使用。

#### 封裝(數(shù)據(jù)的隱藏)

通常,應(yīng)禁止直接訪問一個(gè)對(duì)象中數(shù)據(jù)的實(shí)際表示,而應(yīng)該通過操作接口來訪問,稱為信息隱藏。

#### 屬性私有,get/set

快捷鍵 Command + N = Mac中對(duì)應(yīng)的是:control+enter

可以在get方法里面對(duì)傳入的數(shù)據(jù)做合法性判斷

這就相當(dāng)于銀行取錢,我能看見余額,但不能修改余額

因?yàn)槟闶莗rivate的所以要設(shè)置getter和setter, 如果不需要更改就不用設(shè)置, public安全程度低


示例1:

```java

public class Person {

? ?private String name;

? ? public String getName() {

? ? ? ? return name;

? ? }


? ? public void setName(String name) {

? ? ? ? this.name = name;

? ? }





? ? public Person() {

? ? }


? ? public Person(String name) {

? ? ? ? this.name = name;



? ? }


}


```


示例2:

```java

public class Student{

//名字

private String name;


//學(xué)號(hào)

private int id;


//性別

private char sex;


//年齡

private int age;


public int getAge(){

? ? if(age>120 || age<0){

? ? ? ? this.age=3;

? ? }else{

? ? ? ? this.age=age;

? ? }

? ? return age;

}


public void setAge(int age){

? ? this.age=age;

}


public String getName(){

? ? this.name=name;

}


public void setName(String name){

? ? this.name=name;

}


public int getId(){

? ? return id;

}


public void setId(int id){

? ? this.id=id;

}


public char getSex(){

? ? return sex;

}


public void setSex(char sex){

? ? this.sex=sex;

}


}


//==========

public class a{

{


? ? psvm{

Students s1=new Students();? ? ? ??

s1.setAge(1200);? ? ? ??

System.out.println(s1.getAge());}

? ? }

}



```

#### 作用

###### 1. 提高程序的安全性,保護(hù)數(shù)據(jù)?

###### 2. 隱藏代碼的實(shí)現(xiàn)細(xì)節(jié)

###### 3. 統(tǒng)一接口

###### 4. 系統(tǒng)可維護(hù)性增加了



### 9 繼承

#### 類 = 屬性 + 方法?

但是 鳥類 魚類 蟲類 猴類。。。

類太多了 也要進(jìn)行抽象


1. 繼承的本質(zhì)是對(duì)某一批類的抽象,從而實(shí)現(xiàn)對(duì)世界更好的建模

2. extends的意思是“擴(kuò)展”。子類是父類的擴(kuò)展,使用extends來表示

3. Java中只有單繼承,沒有多繼承!一個(gè)類只能繼承一個(gè)父類

4. 繼承是類與類之間的一種關(guān)系,此外還有依賴、組合、聚合等

5. 繼承關(guān)系的兩個(gè)類,一個(gè)是子類(派生類),一個(gè)是父類(基類)子類繼承父類

6. 子類繼承了父類,就會(huì)擁有父類的全部方法,而private私有屬性及方法無法繼承

7. 在Java中,所有類,都默認(rèn)直接或間接繼承Object類(Ctrl+H可以查看類關(guān)系)

8. 被final修飾的類,無法繼承(斷子絕孫)



### 10 super&this


#### super注意點(diǎn):


###### ?1.super調(diào)用父類的構(gòu)造方法,必須在構(gòu)造方法的第一個(gè)(默認(rèn)調(diào)用)


###### ?2.super必須只能出現(xiàn)在子類的方法或者構(gòu)造方法中


###### ?3.super和this不能同時(shí)調(diào)用構(gòu)造方法


#### VS this


###### 代表的對(duì)象不同:

###### this:本身調(diào)用者這個(gè)對(duì)象

###### super:代表父類對(duì)象的應(yīng)用

###### 前提

###### this:沒有繼承也可以使用

###### super:只能在繼承條件下可以使用

###### 構(gòu)造方法

###### this():本類的構(gòu)造

###### super():父類的構(gòu)造

super與this的區(qū)別:super代表父類對(duì)象的引用,只能在繼承條件下使用;this調(diào)用自身對(duì)象,沒有繼承也可以使用

super(); //隱藏代碼,默認(rèn)調(diào)用了父類的無參構(gòu)造,要寫只能寫第一行





![](media/16913989124163/16916049278831.jpg)





###? 11 方法的重寫

#### 重寫:需要有繼承關(guān)系,子類重寫父類的方法!方法名必須相同

#### 參數(shù)列表必須相同

#### 修飾符可以擴(kuò)大但是不可以縮小

#### public>protected>default>private

#### 拋出的異常:范圍,可以被縮小,但是不能擴(kuò)大:ClassNotFoundException-->Exception(大)

#### 重寫是方法的重寫,與屬性無關(guān)

#### 重寫方法只與非靜態(tài)方法有關(guān),與靜態(tài)方法無關(guān)(靜態(tài)方法不能被重寫)

#### 被static(屬于類,不屬于實(shí)例),final(常量方法),private(私有)修飾的方法不能重寫



![](media/16913989124163/16916380850762.jpg)


![](media/16913989124163/16916051595653.jpg)



```java

public class B{

? ? public static void test(){靜態(tài)方法

? ? ? ? System.out.println("B==>test()")

? ? }

}

public class A extends B{//繼承

? ? public static void test(){

? ? ? ? System.out.println("A==>test()")

? ? }

}

public class Application(){

? ? public static void main(String[] args){

? ? ? ? //方法的調(diào)用只和左邊的定義的類型有關(guān)

? ? ? ? A a = new A();

? ? ? ? a.test();//打印A==>test()

? ? ? ??

? ? ? ? //父類的引用指向了子類,但靜態(tài)方法沒有被重寫

? ? ? ? B b = new A();

? ? ? ? b.test();//打印B==>test()

? ? }

}

修改A.Java,B.java


public class B{

? ? public void test(){//非靜態(tài)方法

? ? ? ? System.out.println("B==>test()");

? ? }

}

public class A extends B{

? ? @Override //重寫了B的方法

? ? public void test(){

? ? ? ? System.out.println("A==>test()");

? ? }

}

//父類的引用指向了子類

B b = new A();

//子類重寫了父類的方法,執(zhí)行子類的方法

b.test();//打印變成了A==>test()

/*

靜態(tài)方法是類的方法,非靜態(tài)方法是對(duì)象的方法。有static時(shí),b調(diào)用了B類的方法,因?yàn)閎是B類定義的。沒有static時(shí),b調(diào)用的是對(duì)象的方法,而b是A類new出來的對(duì)象,調(diào)用A的方法

*/



```



重寫:子類的方法名必須和父類保持一致,方法體不同


被static(屬于類,不屬于實(shí)例),final(常量方法),private(私有)修飾的方法不能重寫


#### 為什么重寫:


父類的功能,子類不一定需要,或者不一定滿足

Alt + Insert ; override;





### 12 多態(tài)

即同一方法可以根據(jù)發(fā)送對(duì)象的不同而采用不同的行為方式

一個(gè)對(duì)象的實(shí)際類型是確定的,但可以指向?qū)ο蟮囊每梢杂泻芏?/p>

#### 多態(tài)存在條件

有繼承關(guān)系

子類重寫父類的方法

父類引用指向子類對(duì)象


#### 注意點(diǎn)


多態(tài)是方法的多態(tài),沒有屬性的多態(tài)


父類和子類,有聯(lián)系 類型轉(zhuǎn)換溢出:ClassCastException

存在條件:繼承關(guān)系,方法需要重寫,父類引用指向了子類對(duì)象

instanceof和類型轉(zhuǎn)換


instanceof引用類型比較,判斷一個(gè)對(duì)象是什么類型

```java


private static int age;

private double score;

public void run(){ }

public static void go(){ }


public static void main(String[] args){

? ? Student s1 = new Student();

? ? System.out.println(Student.age);

? ? System.out.println(Student.score);

? ? System.out.println(s1.ahe);

? ? System.out.println(s1.score);

? ? go();

? ? run();

}



```

#### 多態(tài)的內(nèi)存分析


![](media/16913989124163/16916380480172.jpg)

#### -編譯看左 運(yùn)行看右? 調(diào),但具體調(diào)子類的方法 父.方法();//輸出son。


編譯看左,運(yùn)行看右” 是指在面向?qū)ο缶幊讨?,Java編譯器在編譯時(shí)會(huì)根據(jù)引用變量的類型(左邊)來確定可以調(diào)用哪些方法和屬性,

而在運(yùn)行時(shí)則會(huì)根據(jù)實(shí)際對(duì)象的類型(右邊)來決定執(zhí)行哪個(gè)方法。這涉及到多態(tài)性的概念。


讓我用一個(gè)例子來解釋這個(gè)概念:


假設(shè)有一個(gè)類 Animal 和一個(gè)繼承自 Animal 的類 Dog:

```java

class Animal {

? ? public void makeSound() {

? ? ? ? System.out.println("動(dòng)物發(fā)出聲音");

? ? }

}


class Dog extends Animal {

? ? public void makeSound() {

? ? ? ? System.out.println("汪汪汪!");

? ? }

}


```

```java

Animal myAnimal = new Dog();

myAnimal.makeSound();? // 輸出:"汪汪汪!"


```

**在這里,myAnimal 是一個(gè) Animal 類型的引用,但是它實(shí)際指向了 Dog 類的一個(gè)實(shí)例。**

在編譯時(shí),編譯器看到 myAnimal 是 Animal 類型,所以它知道可以調(diào)用 makeSound 方法。

但是在運(yùn)行時(shí),因?yàn)?myAnimal 實(shí)際上指向 Dog 類的實(shí)例,所以**會(huì)調(diào)用 Dog 類的 makeSound 方法**,從而輸出 "汪汪汪!"。


這就是“編譯看左,運(yùn)行看右”這個(gè)概念的含義。在編譯時(shí),編譯器會(huì)根據(jù)左邊的類型來確定可用的方法和屬性,但在運(yùn)行時(shí),實(shí)際上會(huì)根據(jù)右邊的實(shí)際對(duì)象來執(zhí)行相應(yīng)的方法。






![](media/16913989124163/16916393949656.jpg)




### 13 instanceof (類型轉(zhuǎn)換)引用類型

1. 能否編譯通過,看類是否有關(guān)系,x與y的類(實(shí)際x,y本身就是類)?

2. 若存在父子或子父關(guān)系責(zé)可編譯

3. 編譯過后T/F 看引用指向?qū)ο? 引用變量名x指向的對(duì)象 如果是后面y的子類的實(shí)例化,即是T。

說到底,就是比較左邊的物件? 右邊的大容器能不能裝得下




instanceof 是 Java 中的一個(gè)關(guān)鍵字,用于檢查一個(gè)對(duì)象是否是某個(gè)類的**實(shí)例,或者是否實(shí)現(xiàn)了某個(gè)接口**。它返回一個(gè)布爾值,如果對(duì)象是指定類或接口的實(shí)例,則返回 true,否則返回 false。


instanceof 主要用于實(shí)現(xiàn)多態(tài)性中的類型檢查,讓我們來看一個(gè)例子:


```java

class Animal {

}


class Dog extends Animal {

}


class Cat extends Animal {

}


```

##### 使用 instanceof 來檢查一個(gè)對(duì)象是否是某個(gè)類的實(shí)例:



```java




Animal animal = new Dog();


if (animal instanceof Dog) {

? ? System.out.println("這是一只狗!");

} else if (animal instanceof Cat) {

? ? System.out.println("這是一只貓!");

} else {

? ? System.out.println("這是一只動(dòng)物!");

}




```

在這個(gè)例子中,animal 是一個(gè) Animal 類型的引用,但它實(shí)際指向了 Dog 類的一個(gè)實(shí)例。通過使用 instanceof,我們可以判斷實(shí)際對(duì)象的類型,然后輸出相應(yīng)的信息。



#### instanceof 關(guān)鍵字主要作用和意義:


1. 類型檢查和多態(tài)性: 一個(gè)程序中可能會(huì)有許多不同的類和對(duì)象,而這些類可能存在繼承關(guān)系。通過使用 instanceof,可以在運(yùn)行時(shí)確定對(duì)象的實(shí)際類型,從而進(jìn)行相應(yīng)的操作。這在實(shí)現(xiàn)多態(tài)性時(shí)非常有用,讓不同的對(duì)象以一種統(tǒng)一的方式被處理。

2. 避免類型轉(zhuǎn)換錯(cuò)誤: 在使用繼承和多態(tài)性的情況下,如果嘗試將一個(gè)對(duì)象轉(zhuǎn)換為錯(cuò)誤的類型,會(huì)導(dǎo)致運(yùn)行時(shí)的異常。使用 instanceof 可以在進(jìn)行類型轉(zhuǎn)換之前先檢查對(duì)象的類型,從而避免此類錯(cuò)誤。

3. 動(dòng)態(tài)適應(yīng)性: instanceof 允許程序在運(yùn)行時(shí)根據(jù)對(duì)象的實(shí)際類型做出決策。這種動(dòng)態(tài)適應(yīng)性使得程序可以根據(jù)不同情況做出不同的處理,從而提高了代碼的靈活性和可維護(hù)性。

4. 接口和抽象類判斷: 除了用于類的判斷外,instanceof 也可以用于判斷一個(gè)對(duì)象是否實(shí)現(xiàn)了某個(gè)接口或是抽象類的子類。

5. 安全的類型轉(zhuǎn)換: 在使用類型轉(zhuǎn)換之前使用 instanceof 進(jìn)行檢查,可

以避免不安全的類型轉(zhuǎn)換,從而減少潛在的運(yùn)行時(shí)錯(cuò)誤。


總的來說,instanceof 關(guān)鍵字幫助你處理繼承和多態(tài)性的情況,確保你在操作對(duì)象時(shí)能夠正確地處理不同的對(duì)象類型,從而增強(qiáng)代碼的穩(wěn)定性和可讀性。它是面向?qū)ο缶幊讨幸粋€(gè)重要的工具,幫助你更好地利用Java的特性。




#### 類型轉(zhuǎn)換

在Java中,子類和父類之間可以進(jìn)行類型轉(zhuǎn)換,但需要注意一些規(guī)則和限制。類型轉(zhuǎn)換可以分為向上轉(zhuǎn)型(Upcasting)和向下轉(zhuǎn)型(Downcasting)兩種情況。


##### 1. 向上轉(zhuǎn)型(Upcasting):

向上轉(zhuǎn)型是指將一個(gè)子類對(duì)象賦值給父類引用變量,這是安全的,因?yàn)樽宇愂歉割惖奶鼗?。在向上轉(zhuǎn)型時(shí),你可以調(diào)用父類中定義的方法,但不能調(diào)用子類中特有的方法。


示例:


```java


class Animal {

? ? void sound() {

? ? ? ? System.out.println("動(dòng)物發(fā)出聲音");

? ? }

}


class Dog extends Animal {

? ? void sound() {

? ? ? ? System.out.println("汪汪汪!");

? ? }


? ? void fetch() {

? ? ? ? System.out.println("狗會(huì)接?xùn)|西");

? ? }

}

//編譯看左 運(yùn)行看右

public class Main {

? ? public static void main(String[] args) {

? ? ? ? Animal animal = new Dog();? // 向上轉(zhuǎn)型

? ? ? ? animal.sound();? ? ? ? ? ? ?// 調(diào)用的是 Dog 類中的 sound 方法 汪汪汪

? ? ? ? // animal.fetch();? ? ? ? ? // 錯(cuò)誤!Animal 類沒有 fetch 方法

? ? }

}




```

##### 2. 向下轉(zhuǎn)型(Downcasting):

向下轉(zhuǎn)型是指將一個(gè)父類引用變量轉(zhuǎn)換為子類引用變量,但這需要在編譯時(shí)和運(yùn)行時(shí)都要進(jìn)行**安全檢查**。只有在父類引用實(shí)際上指向一個(gè)**子類對(duì)象**時(shí),向下轉(zhuǎn)型才會(huì)成功。如果轉(zhuǎn)型失敗,會(huì)拋出 ClassCastException 異常。


示例:

```java

class Animal {

? ? void sound() {

? ? ? ? System.out.println("動(dòng)物發(fā)出聲音");

? ? }

}


class Dog extends Animal {

? ? void sound() {

? ? ? ? System.out.println("汪汪汪!");

? ? }


? ? void fetch() {

? ? ? ? System.out.println("狗會(huì)接?xùn)|西");

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? Animal animal = new Dog();? ?// 向上轉(zhuǎn)型

? ? ? ? if (animal instanceof Dog) {

? ? ? ? ? ? Dog myDog = (Dog) animal;? // 向下轉(zhuǎn)型

? ? ? ? ? ? myDog.sound();? ? ? ? ? ? ?// 調(diào)用 Dog 類中的 sound 方法

? ? ? ? ? ? myDog.fetch();? ? ? ? ? ? ?// 調(diào)用 Dog 類中的 fetch 方法

? ? ? ? } else {

? ? ? ? ? ? System.out.println("對(duì)象不是 Dog 類的實(shí)例");

? ? ? ? }

? ? }

}


```

##### instanceof在類型轉(zhuǎn)換中的作用


因此,需要注意的是,向下轉(zhuǎn)型時(shí)需要使用 (子類類型) 進(jìn)行顯式的類型轉(zhuǎn)換,并且最好在轉(zhuǎn)型前使用 **instanceof **來進(jìn)行類型檢查,以避免可能的異常。


父類型引用指向子類型對(duì)象,需要調(diào)用子類所特有的方法時(shí),需要強(qiáng)制類型轉(zhuǎn)換

父類是高類型,子類是低類型;低轉(zhuǎn)高,自動(dòng)轉(zhuǎn)換;高轉(zhuǎn)低,要舍棄。所以強(qiáng)制剝奪轉(zhuǎn)換



#### 子類和父類之間的類型轉(zhuǎn)換在Java中有其優(yōu)點(diǎn)和缺點(diǎn):


#### 優(yōu)點(diǎn):


###### 代碼靈活性:

?類型轉(zhuǎn)換允許你在不同的情境下使用相同的代碼處理不同類型的對(duì)象。這在實(shí)現(xiàn)多態(tài)性和通用代碼時(shí)非常有用,使得代碼更具靈活性和可重用性。

###### 動(dòng)態(tài)適應(yīng)性:

?類型轉(zhuǎn)換允許你在運(yùn)行時(shí)根據(jù)實(shí)際對(duì)象的類型做出決策。這在根據(jù)不同的條件采取不同的操作時(shí)很有用,增加了程序的動(dòng)態(tài)適應(yīng)性。

###### 代碼共享:?

使用父類引用來處理多個(gè)子類對(duì)象,可以將共享的代碼抽象到父類中,避免了重復(fù)編寫相似的代碼,提高了代碼的重用性。

#### 缺點(diǎn):


###### 編譯時(shí)類型檢查不足:

?在向下轉(zhuǎn)型時(shí),如果沒有進(jìn)行適當(dāng)?shù)念愋蜋z查,可能會(huì)導(dǎo)致編譯時(shí)的錯(cuò)誤或者運(yùn)行時(shí)的異常。因此,必須小心地進(jìn)行類型檢查和轉(zhuǎn)換,以避免潛在的錯(cuò)誤。

###### 安全性問題:?

類型轉(zhuǎn)換可能會(huì)引入安全性問題。如果沒有正確地進(jìn)行類型檢查,可能會(huì)在運(yùn)行時(shí)出現(xiàn) ClassCastException 異常,從而導(dǎo)致程序崩潰。

###### 可讀性和維護(hù)性:?

大量的類型轉(zhuǎn)換可能會(huì)使代碼更難以閱讀和理解。特別是在復(fù)雜的繼承關(guān)系中,類型轉(zhuǎn)換可能會(huì)導(dǎo)致代碼的復(fù)雜性,降低代碼的可讀性和可維護(hù)性。

###### 違背封裝原則:?

使用類型轉(zhuǎn)換可能會(huì)違反封裝原則,因?yàn)樗试S在外部訪問子類特有的方法和屬性,從而可能破壞了封裝的隔離性。

總的來說,子類和父類之間的類型轉(zhuǎn)換在合適的情況下可以提高代碼的靈活性和重用性,但也需要小心地進(jìn)行類型檢查,避免潛在的錯(cuò)誤和安全性問題。最佳實(shí)踐是使用類型轉(zhuǎn)換時(shí)要充分理解其優(yōu)缺點(diǎn),并根據(jù)具體情況做出明智的決策。



#### 父類引用指向子類的對(duì)象

把子類轉(zhuǎn)換為父類,(替代老子 )向上轉(zhuǎn)型,會(huì)丟失子類自己原來的特有的方法

把父類轉(zhuǎn)換為子類,(剝奪地位)向下轉(zhuǎn)型,強(qiáng)制轉(zhuǎn)換(丟失精度 ),才調(diào)用子類方法



**類似,子類轉(zhuǎn)父類,會(huì)丟失方法,子類不能繼承父類的私有方法

而父類轉(zhuǎn)子類,(Person-->dog 高轉(zhuǎn)低 向上強(qiáng)轉(zhuǎn) )只需要強(qiáng)制轉(zhuǎn)換,還能使用子類的方法!多好**



方便方法的調(diào)用(轉(zhuǎn)型),減少重復(fù)的代碼,簡潔

### 14?


靜態(tài)變量可以直接用類名訪問,也稱類變量

靜態(tài)變量(或方法)對(duì)于類,所有對(duì)象(實(shí)例)共享

靜態(tài)變量可以直接調(diào)用,但是非靜態(tài)變量不可以直接調(diào)用




### 14 Static

### 作用:

#### 1. 靜態(tài)變量(Static Variables):


靜態(tài)變量是屬于類而不是對(duì)象的變量。它在類的所有對(duì)象之間共享相同的值。在創(chuàng)建一個(gè)對(duì)象時(shí),所有該類的實(shí)例都會(huì)共享同一個(gè)靜態(tài)變量的值。靜態(tài)變量通過使用 static 關(guān)鍵字來聲明。


java

Copy code

class Counter {

? ? static int count = 0;? // 靜態(tài)變量,所有 Counter 對(duì)象共享這個(gè)值


? ? public Counter() {

? ? ? ? count++;? // 每次創(chuàng)建對(duì)象時(shí),計(jì)數(shù)器增加

? ? }


? ? static int getCount() {

? ? ? ? return count;? // 靜態(tài)方法可以訪問靜態(tài)變量

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? Counter c1 = new Counter();

? ? ? ? Counter c2 = new Counter();


? ? ? ? System.out.println("對(duì)象數(shù)量:" + Counter.getCount());? // 輸出:對(duì)象數(shù)量:2

? ? }

}

#### 2. 靜態(tài)方法(Static Methods):


靜態(tài)方法是屬于類而不是對(duì)象的方法。它可以在不創(chuàng)建類的實(shí)例的情況下被調(diào)用。靜態(tài)方法通過使用 static 關(guān)鍵字來聲明。


java

Copy code

class MathUtil {

? ? static int add(int a, int b) {

? ? ? ? return a + b;

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? int result = MathUtil.add(5, 3);? // 調(diào)用靜態(tài)方法

? ? ? ? System.out.println("結(jié)果:" + result);? // 輸出:結(jié)果:8

? ? }

}

#### 3. 靜態(tài)代碼塊(Static Initialization Block):


靜態(tài)代碼塊在類被加載時(shí)執(zhí)行,通常用于進(jìn)行類的初始化操作。它也使用 static 關(guān)鍵字來聲明。


java

Copy code

class MyClass {

? ? static int count;


? ? static {

? ? ? ? count = 10;? // 靜態(tài)代碼塊在類加載時(shí)執(zhí)行

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? System.out.println("Count:" + MyClass.count);? // 輸出:Count:10

? ? }

}

總的來說,static 關(guān)鍵字用于創(chuàng)建與類本身相關(guān)聯(lián)的屬性和方法,而不是與類的實(shí)例相關(guān)聯(lián)。希望這些例子能幫助你理解 static 的概念。如果還有疑問,隨時(shí)提問!







#### 代碼塊

```java

靜態(tài)區(qū)代碼加載類時(shí)一起被初始化,最早執(zhí)行且只執(zhí)行一次(第一次new)

public class Person{

? ? {

? ? ? ? System.out.println("匿名代碼塊");

? ? }

? ? static {

? ? ? ? System.out.println("靜態(tài)代碼塊");

? ? }

? ? public Person(){

? ? ? ? System.out.println("構(gòu)造方法");

? ? }

? ? public static void main(String[] args){

? ? ? ? Person person = new Person();

? ? ? ? System.out.println("=====================")

? ? ? ? Person person2 = new Person();

? ? ? ? System.out.println("=====================")

? ? ? ? Person person3 = new Person();

? ? }

}

//靜態(tài)代碼塊

//匿名代碼塊

//構(gòu)造方法

//======

//匿名代碼塊

//構(gòu)造方法

```



?

####? Math->隨機(jī)數(shù):

###### //靜態(tài)導(dǎo)入包

```java

import static java.lang.Math.random;

public class Application {? ??

? ? public static void main(String[] args) {? ? ? ??

? ? ? ? //第一種隨機(jī)數(shù),不用導(dǎo)包? ? ? ??

? ? ? ? System.out.println(Math.random());?

? ? ? ? //0.7562202902634543? ? ? ??

? ? ? ? //第二種隨機(jī)數(shù),靜態(tài)導(dǎo)入包? ? ? ??

? ? ? ? System.out.println(random());?

? ? ? ? //0.5391606223844663? ??

? ? }

}



```

#### -不能重寫的方法?

1、static方法,屬于類它不屬于實(shí)例? ? ?2、final? 常量? ? ?3、private? 私有類不能重寫



### 15 抽象類 子類強(qiáng)制重寫抽象方法 老子省事 模板設(shè)計(jì)模式

創(chuàng)建一個(gè)人,必須要有五官、身高體重。但是長多帥、多高、多重,你可以自己決定。

接口可以多繼承,抽象單繼承

![](media/16913989124163/16916535745654.jpg)


abstract修飾的類就是抽象類,修飾的方法就是抽象方法

抽象類中可以沒有抽象方法,但有抽象方法的類一定要聲明為抽象類

抽象類不能使用new來創(chuàng)建對(duì)象,它是用來讓子類繼承的

抽象方法只有方法的聲明,沒有實(shí)現(xiàn),讓其子類實(shí)現(xiàn)

子類繼承抽象類,必須實(shí)現(xiàn)抽象類的所有方法, 否則該子類也要聲明為抽象類



編譯器給抽象類添加了一個(gè)無參構(gòu)造方法。

### 16【接口】


#### 接口最能體現(xiàn)OOP的精髓,對(duì) 對(duì)象 的抽象

#### 抽象類是對(duì)事物屬性的抽象,接口是對(duì)行為的抽象


public abstract class? ?Person{

}

pubnlic class Students? enxtends Person{

@Override

? ? public void do Something(){

? ? }

}

類里面有方法的實(shí)現(xiàn),接口里面只有方法的定義。

因?yàn)樗浅橄蟮模辗椒0妫?,所以在類中?shí)現(xiàn)(調(diào)用)接口的時(shí)候,必須要進(jìn)行方法重寫才能使用。


- 在Java編程語言中是一個(gè)抽象類型,是抽象對(duì)象的集合,對(duì)象通常以interface關(guān)鍵字來聲明。

#### 普通類:只有具體實(shí)現(xiàn) 屬性+方法

##### 抽象類:具體實(shí)現(xiàn)和規(guī)范(抽象方法)共存 模版設(shè)計(jì)

##### 接口:只有規(guī)范,無法自己實(shí)現(xiàn) 約束規(guī)范

##### 約束和實(shí)現(xiàn)分離->面向接口編程

接口就是規(guī)范,定義一組規(guī)則,**它的本質(zhì)是契約**,制定好之后大家都要遵守。

OO的精髓,是對(duì)對(duì)象的抽象,最能體現(xiàn)這一點(diǎn)的就是接口。為什么我們討論設(shè)計(jì) 模式都只針對(duì)具備了抽象

能力的語言(比如c++、java、c#等),就是因?yàn)樵O(shè)計(jì)模式所研究的,實(shí)際上就是如何合理的去抽象。



#### 接口的特性


接口是隱式抽象的,當(dāng)聲明一個(gè)接口的時(shí)候,不必使用abstract關(guān)鍵字。

接口中每一個(gè)方法也是隱式抽象的,聲明時(shí)同樣不需要abstract關(guān)鍵字

接口中的方法都是公有的。

實(shí)現(xiàn)

#### 1 接口的聲明

```java

[可見度] interface 接口名稱 [extends 其他的接口名] {? ? ? ?

? ? // 聲明變量??

? ??

? ? // 抽象方法?

}

```

```java

/**

*用戶接口,需要實(shí)現(xiàn)類

*鍛煉抽象的思維

*/

public interface UserService{

? ? //定義的屬性默認(rèn)是靜態(tài)常量:public static final

? ? int age = 10;

? ??

? ? //定義的方法默認(rèn)是公共抽象:public abstract 因此可以省略 不寫

?public abstract? void add(String str);

? ? void delete(String str);

? ? void update(String str);

? ? void query(String str);

}

public interface TimeService{

? ? void timer();

}

```

#### 2 接口的實(shí)現(xiàn)?

```java

/*

抽象類用繼承:extends

接口用實(shí)現(xiàn):implements

類可以實(shí)現(xiàn)接口,需要實(shí)現(xiàn)所有方法!

利用接口實(shí)現(xiàn)偽多繼承~

*/

public class UserServiceImplement implements UserService,TimeService{

? ? @Override

? ? public void add(String str){

? ? ? ??

? ? }

? ??

? ? @Override

? ? public void delete(String str){

? ? ? ??

? ? }

? ??

? ? @Override

? ? public void update(String str){

? ? ? ??

? ? }

? ??

? ? @Override

? ? public void query(String str){

? ? ? ??

? ? }

? ??

? ? @Override

? ? public void timer(){

? ? ? ??

? ? }

}

```

類在實(shí)現(xiàn)接口的方法時(shí),不能拋出強(qiáng)制性異常,只能在接口中,或者繼承接口的抽象類中拋出該強(qiáng)制性異常


#### 在實(shí)現(xiàn)接口的時(shí)候,也要注意一些規(guī)則:

#### Mac快捷鍵是command+回車

###### 1. 一個(gè)類只能繼承一個(gè)類,但是能實(shí)現(xiàn)多個(gè)接口

###### 2. 一個(gè)接口能繼承另一個(gè)接口,這和類之間的繼承比較相似

###### 繼承

###### 3. 接口的繼承使用extends關(guān)鍵字,子接口繼承父類接口的方法


```java


//文件名:Sports.java

public interface Sports{

? ? public void setHomeTeam(String name);

? ? public void setVisitingTeam(String name);

}


//文件名:Football.java

public interface Foorball extends Sports{

? ? public void homeTeamScored(int points);

? ? public void visitingTeamScored(int points)

? ? public void endOfQuarter(int quarter);

}


//文件名:Hockey.java

public interface Hockey extends Sports{

? ? public void homeGoalScored();

? ? public void visitingGoalScored();

? ? public void endOfPeriod(int period);

? ? public void overtimePeriod(int ot);

}

```


#### 多繼承


###### 類不允許多繼承

###### 接口允許多繼承



接口與類相似,一個(gè)接口可以有多個(gè)方法


#### 接口與類的區(qū)別


接口不能被實(shí)例化

接口沒有構(gòu)造方法

接口中所有的方法必須是抽象方法

接口不能包含成員變量,除了static和final變量

接口不是被類繼承,而是被類實(shí)現(xiàn)

接口支持多繼承(實(shí)現(xiàn)類(implements) 可以實(shí)現(xiàn)多個(gè)接口)

實(shí)現(xiàn)類必須要重寫接口中的方法



JDK8之后的新特性,支持在接口中實(shí)現(xiàn)具體方法,但需要default修飾。default修飾方法只能在接口中使用。


### 17 內(nèi)部類

內(nèi)部類:在一個(gè)類的內(nèi)部再定義一個(gè)類


class A{

? ? class B{

? ? ? ??

? ? }

}

A是B的外部類,B是A的內(nèi)部類。


#### 1 成員內(nèi)部類

###### 定義成員內(nèi)部類

```java

public class Outer{

? ? private int id = 10;

? ? public void out(){

? ? ? ? System.out.println("外部類的方法");

? ? }

? ??

? ? //成員內(nèi)部類

? ? public class Inner{//若內(nèi)部類加上static 靜態(tài) 則getOuterId()方法失效。因?yàn)?靜態(tài)? ?

? ? ? ? public void inner(){

? ? ? ? ? ? System.out.println("內(nèi)部類的方法");

? ? ? ? }

? ? ? ? ? ??

? ? ? ? //可以直接使用外部類的屬性/方法

? ? ? ? public void getOuterId(){

? ? ? ? ? ? System.out.println("內(nèi)部類調(diào)用外部類屬性和方法");

? ? ? ? ? ? //創(chuàng)建成員內(nèi)部類之前肯定要?jiǎng)?chuàng)建外部類對(duì)象

? ? ? ? ? ? //即使id不是靜態(tài)變量,out不是靜態(tài)方法,但創(chuàng)建外部類對(duì)象時(shí)已經(jīng)存在。

? ? ? ? ? ? System.out.pirntln(id);

? ? ? ? ? ? out();

? ? ? ? }

? ? }

}

```

#### 實(shí)現(xiàn)內(nèi)部類


```java

import com.oop.demo10.Outer;

public class Application {

public static void main(String[] args) {

Outer outer = new Outer();//通過這個(gè)外部類來實(shí)例化內(nèi)部類

Outer.Inner inner = outer .new Inner();

inner.getID();

```

#### 匿名內(nèi)部類


public class Application{

? ? public static void main(String[] args){

? ? ? ? //匿名內(nèi)部類在多線程中使用,到時(shí)候再深究

? ? ? ? Thread thread = new Thread(new Runnable(){

? ? ? ? ? ? @Override

? ? ? ? ? ? public void run(){

? ? ? ? ? ? ? ? System.out.println("匿名內(nèi)部類實(shí)現(xiàn)線程的邏輯操作");

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //開啟操作

? ? ? ? thread.start();

? ? }

}




# 06 異常

### 1 Error 和 Exception

異常

#### 1.什么是異常

? ? 實(shí)際工作中,遇到的情況不可能是非常完美的。比如:你寫的某個(gè)模塊,用戶輸入不一定符合你的要求、你的程序要打開某個(gè)文件,這個(gè)文件可能不存在或者文件格式不對(duì),你要讀取數(shù)據(jù)庫的數(shù)據(jù),數(shù)據(jù)可能是空的等。我們的程序再跑著,內(nèi)存或硬盤可能滿了。等等。


? ? 軟件程序在運(yùn)行過程中,非??赡苡龅絼倓偺岬降倪@些異常問題,我們叫異常,英文是:Exception,意思是例外。這些,例外情況,或者叫異常,怎么讓我們寫的程序做出合理的處理。而不至于程序崩潰。


? ? 異常指程序運(yùn)行中出現(xiàn)的不期而至的各種狀況如:文件找不到、網(wǎng)絡(luò)連接失敗、非法參數(shù)等。異常發(fā)生在程序運(yùn)行期間它影響了正常的程序執(zhí)行流程。


要理解Java異常處理是如何工作的,需要掌握以下三種類型的異常:


#### 2 三種類型的異常

###### 檢查性異常:

最具代表的檢查性異常是用戶錯(cuò)誤或問題引起的異常,這是程序員無法預(yù)見的例如要打開一個(gè)不存在文件時(shí),一個(gè)異常就發(fā)生了,這些異常在編譯時(shí)不能被簡單地忽略。

###### 運(yùn)行時(shí)異常:

運(yùn)行時(shí)異常是可能被程序員避免的異常。與檢查性異常相反,運(yùn)行時(shí)異??梢栽诰幾g時(shí)被忽略。

###### 錯(cuò)誤ERROR:

錯(cuò)誤不是異常,而是脫離程序員控制的冋題。錯(cuò)誤在代碼中通常被忽略。例如,當(dāng)棧溢出時(shí),一個(gè)錯(cuò)誤就發(fā)生了,它們在編譯也檢查不到的。


#### 3.異常體系結(jié)構(gòu)

![](media/16913989124163/16916578779766.jpg)


Java把異常當(dāng)作對(duì)象來處理,并定義一個(gè)基類 java. lang.Throwable作為所有異常的超類。

在 Java API中已經(jīng)定義了許多異常類,這些異常類分為兩大類,錯(cuò)誤Error和異常 Exception。

在這里插入圖片描述

#### Error


Error類對(duì)象由Java虛擬機(jī)生成并拋出,大多數(shù)錯(cuò)誤與代碼編寫者所執(zhí)行的操作無關(guān)。

Java虛擬機(jī)運(yùn)行錯(cuò)誤( Virtual Machine Error),當(dāng)JVM不再有繼續(xù)執(zhí)行操作所需的內(nèi)存資源時(shí),將出現(xiàn) OutofMemory Error。這些異常發(fā)生時(shí),Java虛擬機(jī)(JVM)一般會(huì)選擇線程終止。

還有發(fā)生在虛擬機(jī)試圖執(zhí)行應(yīng)用時(shí),如類定義錯(cuò)誤( NoClass Deffound error)、鏈接錯(cuò)誤( Linkage Error)。這些錯(cuò)誤是不可查的,因?yàn)樗鼈冊趹?yīng)用程序的控制和處理能力之外,而且絕大多數(shù)是程序運(yùn)行時(shí)不允許出現(xiàn)的狀況。

#### Exception

##### 運(yùn)行時(shí)異常(還有非運(yùn)行異常 檢查異常)

在 Exception分支中有一個(gè)重要的子類 Runtime Exception(運(yùn)行時(shí)異常)

ArraylndexOutOfBoundsException(數(shù)組下標(biāo)越界)

NullPointerException(空指針異常)

ArithmeticException(算術(shù)異常)

Missing Resource Exception(丟失資源)

ClassNotFound Exception(找不到類)等異常,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。

這些異常一般是由程序邏輯錯(cuò)誤引起的,程序應(yīng)該從邏輯角度盡可能避免這類異常的發(fā)生;

#### Error和 Exception的區(qū)別:

###### Error通常是災(zāi)難性的致命的錯(cuò)誤,是程序無法控制和處理的,當(dāng)出現(xiàn)這些異常時(shí),Java虛擬機(jī)(JVM)一般會(huì)選擇終止線程;

###### Exception通常情況下是可以被程序處理的,并且在程序中應(yīng)該盡可能的去處理這些異常。



### 2 Java異常處理機(jī)制與處理異常

### 拋出異常

### 捕獲異常

異常處理五個(gè)關(guān)鍵字:

try、catch、 finally、throw、throws


```java


public static void main(String[] args) {

? ? ? ? int a=1;

? ? ? ? int b=0;



? ? ? ? try{

? ? ? ? ? ? System.out.println(a/b);

? ? ? ? }catch (Error e){

? ? ? ? ? ? System.out.println("Error");

? ? ? ? }catch(Exception e){

? ? ? ? ? ? System.out.println("Exception");

? ? ? ? }catch (Throwable t){

? ? ? ? ? ? System.out.println("Throwable");

? ? ? ? }finally {

? ? ? ? ? ? System.out.println("finally");

? ? ? ? }

? ? }

? ? public void a(){b();}

? ? public void b(){a();}

? ??

? ??


```

```java

int a = 1;

int b = 0;


try{

// try 監(jiān)控區(qū)域

if(b == 0)

{

? ? // 主動(dòng)拋出異常,一般在方法上使用

throw new ArithmeticException();?

}

System.out.println(a/b);

}catch (ArithmeticException e){

// catch 捕獲異常

System.out.println("程序出現(xiàn)異常,變量b不能為0");

}catch (Throwable t){

// catch 可以有多個(gè)

t.printstackTrace(); // 打印錯(cuò)誤的棧信息

System.out.println("從小到大捕獲異常");

}finally {

// 處理善后工作

System.out.println("finally"); // 可以不要,多用于IO、資源的關(guān)閉。

}


// 假設(shè)在這個(gè)方法中,處理不了這個(gè)異常,在方法上拋出異常。

public void test(int a,int b) throws ArithmeticException{

if(b == 0)

{

throw new ArithmeticException();?

}

}


```

#### throws和throw的區(qū)別

是不管程序有沒有異常,只要執(zhí)行到throw語句就一定會(huì)拋一個(gè)異常

快捷鍵:mac command+option+T


### 3.自定義異常

使用Java內(nèi)置的異常類可以描述在編程時(shí)岀現(xiàn)的大部分異常情況。除此之外,用戶還可以自定義異常。用戶自定義異常類,只需繼承 Exception類即可。

在程序中使用自定義異常類,大體可分為以下幾個(gè)步驟:

創(chuàng)建自定義異常類。

在方法中通過 throw關(guān)鍵字拋出異常對(duì)象。

如果在當(dāng)前拋出異常的方法中處理異常,可以使用try- catch語句捕獲并處理;否則在方法的聲明處通過 throws關(guān)鍵字指明要拋岀給方法調(diào)用者的異常,繼續(xù)進(jìn)行下一步操作。

在出現(xiàn)異常方法的調(diào)用者中捕獲并處理異常。

在這里插入圖片描述

5.總結(jié)

處理運(yùn)行時(shí)異常時(shí),采用邏輯去合理規(guī)避同時(shí)輔助 try-catch ;

處理在多重 catch塊后面,可以加一個(gè) catch( Exception)來處理可能會(huì)被遺漏的異常;

對(duì)于不確定的代碼,也可以加上try- catch,處理潛在的異常;

盡量去處理異常,切忌只是簡單地調(diào)用 printStackTrace0去打印輸出;

具體如何處理異常,要根據(jù)不同的業(yè)務(wù)需求和異常類型去決定;

盡量添加 finally!語句塊去釋放占用的資源。

-=========================

Java把溢出當(dāng)做對(duì)象來處理,并定義了一個(gè)基類Java.lang.Throwable作為所有異常的超類。


Java語言定義了許多異常類在Java.lang標(biāo)準(zhǔn)包中,主要分為Error和Exception兩大類。


img



五個(gè)關(guān)鍵字try、catch、finally、throw、throws


使用try和catch關(guān)鍵字可以捕獲異常。try/catch代碼塊放在異??赡馨l(fā)生的地方。


try/catch代碼塊中的代碼稱為保護(hù)代碼。


finally區(qū)可以不要,在IO流,資源關(guān)閉時(shí)使用。


捕獲多個(gè)溢出:從小到大!


IDEA快捷鍵:選中健康區(qū)域代碼-->Ctrl + Alt + T

? ??

拋出異常


throws是用來聲明一個(gè)方法可能拋出的所有異常信息,throws是將異常聲明但是不處理,而是將異常往上傳,誰調(diào)用我就交給誰處理。而throw則是指拋出的一個(gè)具體的異常類型


throws是用在方法名尾部,可以聲明拋出多個(gè)溢出,多個(gè)溢出之間用逗號(hào)隔開。





import java.io.*;

public class className{

? ? public void withdraw(double amount) throws RemoteException,InsufficientFundsException{

? ? ? ? //Method implementation

? ? }

? ? //Remainder of class definition

}

throw是用在方法體內(nèi),主動(dòng)拋出異常


public class ThrowTest{

? ? public static void main(String[] args){

? ? ? ? int a = 1;

? ? ? ? int b = 0;

? ? ? ??

? ? ? ? try{

? ? ? ? ? ? System.out.println(divide(a,b));

? ? ? ? }catch (Exception e){

? ? ? ? ? ? System.out.println("分母不能為0");

? ? ? ? ? ? //e.printStackTrace();

? ? ? ? }

? ? }

? ??

? ? public static double divide(int a,int b){

? ? ? ? if(b == 0){

? ? ? ? ? ? //主動(dòng)拋出異常

? ? ? ? ? ? throw new ArithmeticException();

? ? ? ? }

? ? ? ? return 1.0*a/b;

? ? }

}

自定義異常


在這里插入圖片描述


//自定義的異常類

public class MyException extends Exception{

? ? private int detail;

? ??

? ? public Myexception(int a){

? ? ? ? this.detail = a;

? ? }

? ??

? ? //異常的處理信息

? ? //tostring

? ? @Override

? ? public String toString(){

? ? ? ? return "Myexception{" + "detail=" + detail + "}";

? ? }

}

public class Appcication{

? ? //可能存在異常方法

? ? static void test(int a) throws MyException{

? ? ? ? System.out.println("傳遞的參數(shù)為:" + a);

? ? ? ? if(a>10){

? ? ? ? ? ? throw new MyException(a);//拋出

? ? ? ? }

? ? ? ? System.out.println("ok");

? ? }

}


public static void main(String[] args){

? ? try{

? ? ? ? test(11);

? ? }catch (MyException e){

? ? ? ? System.out.println("MyException=>" + e);

? ? }

}

#### 總結(jié)


處理運(yùn)行是異常時(shí),采用邏輯去合理規(guī)避,同時(shí)輔助try-catch處理

在多重catch塊后面,可以加一個(gè)catch(Exception)來處理可能會(huì)被遺漏的異常

對(duì)于不確定的代碼,也可以加上try-catch,處理潛在的異常

盡量去處理異常,切忌只是簡單的調(diào)用printStackTrace()去打印輸出

具體如何處理異常,要根據(jù)不同的業(yè)務(wù)需求和異常類型去決定

盡量添加finally語句塊去釋放占用的資源。


來杯JAVA冷靜一下_05面向?qū)ο骭06異常_230809的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
澳门| 肃宁县| 岳池县| 玉林市| 化州市| 湖南省| 贵定县| 马公市| 卓尼县| 武邑县| 靖江市| 清镇市| 舟山市| 泰安市| 静宁县| 桦南县| 夏邑县| 多伦县| 大悟县| 忻城县| 富阳市| 北票市| 义马市| 八宿县| 文成县| 安溪县| 从江县| 海林市| 全南县| 磐石市| 洛扎县| 通化市| 泊头市| 丰城市| 肥乡县| 郎溪县| 日照市| 遵义市| 武宣县| 瑞安市| 丘北县|