中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)技術(shù)部獎懲制度快速建站網(wǎng)站

網(wǎng)站建設(shè)技術(shù)部獎懲制度,快速建站網(wǎng)站,企業(yè)簡介怎么寫吸引人,網(wǎng)站建設(shè)運營必備人員學(xué)習(xí)面向?qū)ο髢?nèi)容的三條主線 Java類及類的成員:(重點)屬性、方法、構(gòu)造器;(熟悉)代碼塊、內(nèi)部類面向?qū)ο蟮奶卣?amp;#xff1a;封裝、繼承、多態(tài)、(抽象)其他關(guān)鍵字的使用:…

學(xué)習(xí)面向?qū)ο髢?nèi)容的三條主線

  • Java類及類的成員:(重點)屬性、方法、構(gòu)造器;(熟悉)代碼塊、內(nèi)部類
  • 面向?qū)ο蟮奶卣?#xff1a;封裝、繼承、多態(tài)、(抽象)
  • 其他關(guān)鍵字的使用:this、super、package、import、static、final、interface、abstract等

1. 面向?qū)ο缶幊谈攀?/h2>

1.1 程序設(shè)計的思路

面向?qū)ο?#xff0c;是軟件開發(fā)中的一類編程風(fēng)格、開發(fā)范式。除了面向?qū)ο?/code>,還有面向過程指令式編程函數(shù)式編程。在所有的編程范式中,我們接觸最多的還是面向過程和面向?qū)ο髢煞N。

類比:史書類型

  • 紀(jì)傳體:以人物傳記為中心,“本紀(jì)”敘述帝王,“世家”記敘王侯封國和特殊人物,“列傳”記敘民間人物。
  • 編年體:按年、月、日順序編寫。
  • 國別體:是一部分國記事的歷史散文,分載多國歷史。

早期先有面向過程思想,隨著軟件規(guī)模的擴大,問題復(fù)雜性的提高,面向過程的弊端越來越明顯,出現(xiàn)了面向?qū)ο笏枷氩⒊蔀槟壳爸髁鞯姆绞健?/p>

1. 面向過程的程序設(shè)計思想(Process-Oriented Programming),簡稱POP

  • 關(guān)注的焦點是過程:過程就是操作數(shù)據(jù)的步驟。如果某個過程的實現(xiàn)代碼重復(fù)出現(xiàn),那么就可以把這個過程抽取為一個函數(shù)。這樣就可以大大簡化冗余代碼,便于維護(hù)。
  • 典型的語言:C語言
  • 代碼結(jié)構(gòu):以函數(shù)為組織單位。
  • 是一種“執(zhí)行者思維”,適合解決簡單問題。擴展能力差、后期維護(hù)難度較大。

2. 面向?qū)ο蟮某绦蛟O(shè)計思想( Object Oriented Programming),簡稱OOP

  • 關(guān)注的焦點是:在計算機程序設(shè)計過程中,參照現(xiàn)實中事物,將事物的屬性特征、行為特征抽象出來,用類來表示。
  • 典型的語言:Java、C#、C++、Python、Ruby和PHP等
  • 代碼結(jié)構(gòu):以為組織單位。每種事物都具備自己的屬性行為/功能。
  • 是一種“設(shè)計者思維”,適合解決復(fù)雜問題。代碼擴展性強、可維護(hù)性高。

1.2 由實際問題考慮如何設(shè)計程序

思考1:如何開車?

面向過程思想思考問題時,我們首先思考“怎么按步驟實現(xiàn)?”并將步驟對應(yīng)成方法,一步一步,最終完成。 這個適合簡單任務(wù),不需要過多協(xié)作的情況。針對如何開車,可以列出步驟:請?zhí)砑訄D片描述
面向過程適合簡單、不需要協(xié)作的事務(wù),重點關(guān)注如何執(zhí)行。

思考2:如何造車?

造車太復(fù)雜,需要很多協(xié)作才能完成。此時我們思考的是“車怎么設(shè)計?”,而不是“怎么按特定步驟造車的問題”。這就是思維方式的轉(zhuǎn)變,前者就是面向?qū)ο笏枷?。所?#xff0c;面向?qū)ο?Oriented-Object)思想更契合人的思維模式。

用面向?qū)ο笏枷胨伎肌叭绾卧O(shè)計車”:
請?zhí)砑訄D片描述
自然地,我們就會從“車由什么組成”開始思考。發(fā)現(xiàn),車由如下結(jié)構(gòu)組成:
請?zhí)砑訄D片描述
我們找輪胎廠完成制造輪胎的步驟,發(fā)動機廠完成制造發(fā)動機的步驟,…;這樣,大家可以同時進(jìn)行車的制造,最終進(jìn)行組裝,大大提高了效率。但是,具體到輪胎廠的一個流水線操作,仍然是有步驟的,還是離不開面向過程思維!

因此,面向?qū)ο罂梢詭椭覀儚暮暧^上把握、從整體上分析整個系統(tǒng)。 但是,具體到實現(xiàn)部分的微觀操作(就是一個個方法),仍然需要面向過程的思路去處理。

注意: 我們千萬不要把面向過程和面向?qū)ο髮α⑵饋?。他們是相輔相成的。面向?qū)ο箅x不開面向過程!

類比舉例1:
請?zhí)砑訄D片描述

當(dāng)需求單一,或者簡單時,我們一步步去操作沒問題,并且效率也挺高。
可隨著需求的更改,功能的增多,發(fā)現(xiàn)需要面對每一個步驟很麻煩了,這時就開始思索,**能不能把這些步驟和功能進(jìn)行封裝,封裝時根據(jù)不同的功能,進(jìn)行不同的封裝,功能類似的封裝在一起。**這樣結(jié)構(gòu)就清晰了很多。用的時候,找到對應(yīng)的類就可以了。這就是面向?qū)ο蟮乃枷搿?/p>

類比舉例2:人把大象裝進(jìn)冰箱

  • 面向過程
1.打開冰箱2.把大象裝進(jìn)冰箱3.把冰箱門關(guān)住
  • 面向?qū)ο?/li>
{打開(冰箱){冰箱.開門();	}操作(大象){大象.進(jìn)入(冰箱);}關(guān)閉(冰箱){   冰箱.關(guān)門();     }
}冰箱{開門(){ }  關(guān)門(){ }
}大象{進(jìn)入(冰箱){  }
}

2. Java語言的基本元素:類和對象

2.1 引入

人認(rèn)識世界,其實就是面向?qū)ο蟮摹1热?#xff0c;我們認(rèn)識一下美人魚(都沒見過)
請?zhí)砑訄D片描述
經(jīng)過“仔細(xì)學(xué)習(xí)”,發(fā)現(xiàn)美人魚通常具備一些特征:

  • 女孩
  • 有魚尾
  • 美麗

這個總結(jié)的過程,其實是抽象化的過程。抽象出來的美人魚的特征,可以歸納為一個美人魚類。而圖片中的都是這個類呈現(xiàn)出來的具體的對象。

2.2 類和對象概述

類(Class)對象(Object)是面向?qū)ο蟮暮诵母拍睢?br /> 1、什么是類
:具有相同特征的事物的抽象描述,是抽象的、概念上的定義。
2、什么是對象
對象:實際存在的該類事物的每個個體,是具體的,因而也稱為實例(instance)。

請?zhí)砑訄D片描述
可以理解為:類 => 抽象概念的人對象 => 實實在在的某個人

請?zhí)砑訄D片描述

請?zhí)砑訄D片描述
3、類與對象的關(guān)系錯誤理解

曰:“白馬非馬,可乎?”
曰:“可?!?曰:“何哉?”
曰:“馬者,所以命形也。白者,所以命色也。命色者,非命形也,故曰白馬非馬?!?

請?zhí)砑訄D片描述

2.3 類的成員概述

面向?qū)ο蟪绦蛟O(shè)計的重點是類的設(shè)計

類的設(shè)計,其實就是類的成員的設(shè)計

  • 現(xiàn)實世界的生物體,大到鯨魚,小到螞蟻,都是由最基本的細(xì)胞構(gòu)成的。同理,Java代碼世界是由諸多個不同功能的構(gòu)成的。

請?zhí)砑訄D片描述

  • 現(xiàn)實生物世界中的細(xì)胞又是由什么構(gòu)成的呢?細(xì)胞核、細(xì)胞質(zhì)、…
    Java中用類class來描述事物也是如此。類,是一組相關(guān)屬性行為的集合,這也是類最基本的兩個成員。

    • 屬性:該類事物的狀態(tài)信息。對應(yīng)類中的成員變量
      • 成員變量 <=> 屬性 <=> Field
    • 行為:該類事物要做什么操作,或者基于事物的狀態(tài)能做什么。對應(yīng)類中的成員方法
      • (成員)方法 <=> 函數(shù) <=> Method
  • 舉例:
    請?zhí)砑訄D片描述

2.4 面向?qū)ο笸瓿晒δ艿娜襟E(重要)

步驟1:類的定義

類的定義使用關(guān)鍵字:class。格式如下:

[修飾符] class 類名{屬性聲明;方法聲明;
}

舉例1:

public class Person{//聲明屬性ageint age ;	                   //聲明方法showAge()public void eat() {        System.out.println("人吃飯");}
}

舉例2:

public class Dog{//聲明屬性String type; //種類String nickName; //昵稱String hostName; //主人名稱//聲明方法public void eat(){ //吃東西System.out.println("狗狗進(jìn)食");		}
}
public class Person{String name;char gender;Dog dog;//喂寵物public void feed(){dog.eat();}
}

步驟2:對象的創(chuàng)建

請?zhí)砑訄D片描述

  • 創(chuàng)建對象,使用關(guān)鍵字:new
  • 創(chuàng)建對象語法:
//方式1:給創(chuàng)建的對象命名
//把創(chuàng)建的對象用一個引用數(shù)據(jù)類型的變量保存起來,這樣就可以反復(fù)使用這個對象了
類名 對象名 = new 類名();//方式2:
new 類名()//也稱為匿名對象
  • 舉例:
class PersonTest{public static void main(String[] args){//創(chuàng)建Person類的對象Person per = new Person();//創(chuàng)建Dog類的對象Dog dog = new Dog();}
}

步驟3:對象調(diào)用屬性或方法

  • 對象是類的一個實例,必然具備該類事物的屬性和行為(即方法)。

  • 使用"對象名.屬性" 或 "對象名.方法"的方式訪問對象成員(包括屬性和方法)

舉例1:

//聲明Animal類
public class Animal { //動物類public int legs;public void eat() {System.out.println("Eating.");}public void move() {System.out.println("Move.");}
}
//聲明測試類
public class AnimalTest {public static void main(String args[]) {//創(chuàng)建對象Animal xb = new Animal();xb.legs = 4;//訪問屬性System.out.println(xb.legs);xb.eat();//訪問方法xb.move();//訪問方法}
}

圖示理解:請?zhí)砑訄D片描述
舉例2:針對前面步驟1的舉例2:類的實例化(創(chuàng)建類的對象)

public class Game{public static void main(String[] args){Person p = new Person();//通過Person對象調(diào)用屬性p.name = "康師傅";p.gender = '男';p.dog = new Dog(); //給Person對象的dog屬性賦值//給Person對象的dog屬性的type、nickname屬性賦值p.dog.type = "柯基犬";p.dog.nickName = "小白";//通過Person對象調(diào)用方法p.feed();}
}

2.5 匿名對象 (anonymous object)

  • 我們也可以不定義對象的句柄,而直接調(diào)用這個對象的方法。這樣的對象叫做匿名對象。
    • 如:new Person().shout();
  • 使用情況
    • 如果一個對象只需要進(jìn)行一次方法調(diào)用,那么就可以使用匿名對象。
    • 我們經(jīng)常將匿名對象作為實參傳遞給一個方法調(diào)用。

3. 對象的內(nèi)存解析

3.1 JVM內(nèi)存結(jié)構(gòu)劃分

HotSpot Java虛擬機的架構(gòu)圖如下。其中我們主要關(guān)心的是運行時數(shù)據(jù)區(qū)部分(Runtime Data Area)。
請?zhí)砑訄D片描述
其中:

堆(Heap):此內(nèi)存區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內(nèi)存。這一點在Java虛擬機規(guī)范中的描述是:所有的對象實例以及數(shù)組都要在堆上分配。

棧(Stack):是指虛擬機棧。虛擬機棧用于存儲局部變量等。局部變量表存放了編譯期可知長度的各種基本數(shù)據(jù)類型(boolean、byte、char、short、int、float、long、double)、對象引用(reference類型,它不等同于對象本身,是對象在堆內(nèi)存的首地址)。 方法執(zhí)行完,自動釋放。

方法區(qū)(Method Area):用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。

3.2 對象內(nèi)存解析

舉例:

class Person { //類:人String name;int age;boolean isMale;
}public class PersonTest { //測試類public static void main(String[] args) {Person p1 = new Person();p1.name = "趙同學(xué)";p1.age = 20;p1.isMale = true;Person p2 = new Person();p2.age = 10;Person p3 = p1;p3.name = "郭同學(xué)";}
}

內(nèi)存解析圖:

請?zhí)砑訄D片描述

說明:

  • 堆:凡是new出來的結(jié)構(gòu)(對象、數(shù)組)都放在堆空間中。
  • 對象的屬性存放在堆空間中。
  • 創(chuàng)建一個類的多個對象(比如p1、p2),則每個對象都擁有當(dāng)前類的一套"副本"(即屬性)。當(dāng)通過一個對象修改其屬性時,不會影響其它對象此屬性的值。
  • 當(dāng)聲明一個新的變量使用現(xiàn)有的對象進(jìn)行賦值時(比如p3 = p1),此時并沒有在堆空間中創(chuàng)建新的對象。而是兩個變量共同指向了堆空間中同一個對象。當(dāng)通過一個對象修改屬性時,會影響另外一個對象對此屬性的調(diào)用。

面試題:對象名中存儲的是什么呢?

答:對象地址

public class StudentTest{public static void main(String[] args){System.out.println(new Student());//Student@7852e922Student stu = new Student();System.out.println(stu);//Student@4e25154fint[] arr = new int[5];System.out.println(arr);//[I@70dea4e}
}

直接打印對象名和數(shù)組名都是顯示“類型@對象的hashCode值",所以說類、數(shù)組都是引用數(shù)據(jù)類型,引用數(shù)據(jù)類型的變量中存儲的是對象的地址,或者說指向堆中對象的首地址。

請?zhí)砑訄D片描述

4. 類的成員之一:成員變量(field)

4.1 如何聲明成員變量

  • 語法格式:
[修飾符1] class 類名{[修飾符2] 數(shù)據(jù)類型 成員變量名 [= 初始化值]; 
}
  • 說明:
    • 位置要求:必須在類中,方法外
    • 修飾符2(暫不考慮)
      • 常用的權(quán)限修飾符有:private、缺省、protected、public
      • 其他修飾符:static、final
    • 數(shù)據(jù)類型
      • 任何基本數(shù)據(jù)類型(如int、Boolean) 或 任何引用數(shù)據(jù)類型。
    • 成員變量名
      • 屬于標(biāo)識符,符合命名規(guī)則和規(guī)范即可。
    • 初始化值
      • 根據(jù)情況,可以顯式賦值;也可以不賦值,使用默認(rèn)值

示例:

public class Person{private int age;             //聲明private變量 agepublic String name =Lila;    //聲明public變量 name
}

4.2 成員變量 vs 局部變量

1、變量的分類:成員變量與局部變量

  • 在方法體外,類體內(nèi)聲明的變量稱為成員變量。
  • 在方法體內(nèi)部等位置聲明的變量稱為局部變量。

請?zhí)砑訄D片描述

其中,static可以將成員變量分為兩大類,靜態(tài)變量和非靜態(tài)變量。其中靜態(tài)變量又稱為類變量,非靜態(tài)變量又稱為實例變量或者屬性。接下來先學(xué)習(xí)實例變量。

2、成員變量 與 局部變量 的對比

  • 相同點

    • 變量聲明的格式相同: 數(shù)據(jù)類型 變量名 = 初始化值
    •    	變量必須先聲明、后初始化、再使用。
      
    • 變量都有其對應(yīng)的作用域。只在其作用域內(nèi)是有效的
  • 不同點

1、聲明位置和方式
(1)實例變量:在類中方法外
(2)局部變量:在方法體{}中或方法的形參列表、代碼塊中

2、在內(nèi)存中存儲的位置不同
(1)實例變量:堆
(2)局部變量:棧

3、生命周期
(1)實例變量:和對象的生命周期一樣,隨著對象的創(chuàng)建而存在,隨著對象被GC回收而消亡,
而且每一個對象的實例變量是獨立的。
(2)局部變量:和方法調(diào)用的生命周期一樣,每一次方法被調(diào)用而在存在,隨著方法執(zhí)行的結(jié)束而消亡,
而且每一次方法調(diào)用都是獨立。

4、作用域
(1)實例變量:通過對象就可以使用,本類中直接調(diào)用,其他類中“對象.實例變量”
(2)局部變量:出了作用域就不能使用

5、修飾符(后面來講)
(1)實例變量:public,protected,private,final,volatile,transient等
(2)局部變量:final

6、默認(rèn)值
(1)實例變量:有默認(rèn)值
(2)局部變量:沒有,必須手動初始化。其中的形參比較特殊,靠實參給它初始化。

3、對象屬性的默認(rèn)初始化賦值

當(dāng)一個對象被創(chuàng)建時,會對其中各種類型的成員變量自動進(jìn)行初始化賦值。
請?zhí)砑訄D片描述
4、舉例

class Person {//人類//1.屬性String name;//姓名int age = 1;//年齡boolean isMale;//是否是男性public void show(String nation) {//nation:局部變量String color;//color:局部變量color = "yellow";}
}//測試類
class PersonTest {public static void main(String[] args) {Person p = new Person();p.show("CHN");}
}

請?zhí)砑訄D片描述

5. 類的成員之二:方法(method)

5.1 方法的引入

請?zhí)砑訄D片描述
《街霸》游戲中,每次人物出拳、出腳或跳躍等動作都需要編寫50-80行的代碼,在每次出拳、出腳或跳躍的地方都需要重復(fù)地編寫這50-80行代碼,這樣程序會變得很臃腫,可讀性也非常差。為了解決代碼重復(fù)編寫的問題,可以將出拳、出腳或跳躍的代碼提取出來放在一個{}中,并為這段代碼起個名字,這樣在每次的出拳、出腳或跳躍的地方通過這個名字來調(diào)用這個{}的代碼就可以了。

上述過程中,所提取出來的代碼可以被看作是程序中定義的一個方法,程序在需要出拳、出腳或跳躍時調(diào)用該方法即可。

5.2 方法(method、函數(shù))的理解

  • 方法是類或?qū)ο笮袨樘卣鞯某橄?#xff0c;用來完成某個功能操作。在某些語言中也稱為函數(shù)過程。

  • 將功能封裝為方法的目的是,可以實現(xiàn)代碼重用,減少冗余,簡化代碼

  • Java里的方法不能獨立存在,所有的方法必須定義在類里。

  • 舉例1:

    • Math.random()的random()方法
    • Math.sqrt(x)的sqrt(x)方法
    • System.out.println(x)的println(x)方法
    • new Scanner(System.in).nextInt()的nextInt()方法
    • Arrays類中的binarySearch()方法、sort()方法、equals()方法
  • 舉例2:

    public class Person{private int age;public int getAge()  {  //聲明方法getAge()return age; }public void setAge(int i) {  //聲明方法setAgeage = i;        //將參數(shù)i的值賦給類的成員變量age}
    }

5.3 如何聲明方法

1、聲明方法的語法格式

[修飾符] 返回值類型 方法名([形參列表])[throws 異常列表]{方法體的功能代碼
}

(1)一個完整的方法 = 方法頭 + 方法體。

  • 方法頭就是[修飾符] 返回值類型 方法名([形參列表])[throws 異常列表],也稱為方法簽名。通常調(diào)用方法時只需要關(guān)注方法頭就可以,從方法頭可以看出這個方法的功能和調(diào)用格式。
  • 方法體就是方法被調(diào)用后要執(zhí)行的代碼。對于調(diào)用者來說,不了解方法體如何實現(xiàn)的,并不影響方法的使用。

(2)方法頭可能包含5個部分

  • 修飾符:可選的。方法的修飾符也有很多,例如:public、protected、private、static、abstract、native、final、synchronized等,后面會一一學(xué)習(xí)。

    • 其中,權(quán)限修飾符有public、protected、private。在講封裝性之前,我們先默認(rèn)使用pulbic修飾方法。
    • 其中,根據(jù)是否有static,可以將方法分為靜態(tài)方法和非靜態(tài)方法。其中靜態(tài)方法又稱為類方法,非靜態(tài)方法又稱為實例方法。咱們在講static前先學(xué)習(xí)實例方法。
  • 返回值類型: 表示方法運行的結(jié)果的數(shù)據(jù)類型,方法執(zhí)行后將結(jié)果返回到調(diào)用者。

    • 無返回值,則聲明:void
    • 有返回值,則聲明出返回值類型(可以是任意類型)。與方法體中“return 返回值”搭配使用
  • 方法名:屬于標(biāo)識符,命名時遵循標(biāo)識符命名規(guī)則和規(guī)范,“見名知意”

  • 形參列表:表示完成方法體功能時需要外部提供的數(shù)據(jù)列表。可以包含零個,一個或多個參數(shù)。

    • 無論是否有參數(shù),()不能省略
    • 如果有參數(shù),每一個參數(shù)都要指定數(shù)據(jù)類型和參數(shù)名,多個參數(shù)之間使用逗號分隔,例如:
      • 一個參數(shù): (數(shù)據(jù)類型 參數(shù)名)
      • 二個參數(shù): (數(shù)據(jù)類型1 參數(shù)1, 數(shù)據(jù)類型2 參數(shù)2)
    • 參數(shù)的類型可以是基本數(shù)據(jù)類型、引用數(shù)據(jù)類型
  • throws 異常列表:可選,在【異常處理】章節(jié)再講

(3)方法體:方法體必須有{}括起來,在{}中編寫完成方法功能的代碼

(4)關(guān)于方法體中return語句的說明:

  • return語句的作用是結(jié)束方法的執(zhí)行,并將方法的結(jié)果返回去

  • 如果返回值類型不是void,方法體中必須保證一定有 return 返回值; 語句,并且要求該返回值結(jié)果的類型與聲明的返回值類型一致或兼容。

  • 如果返回值類型為void時,方法體中可以沒有return語句,如果要用return語句提前結(jié)束方法的執(zhí)行,那么return后面不能跟返回值,直接寫return ; 就可以。

  • return語句后面就不能再寫其他代碼了,否則會報錯:Unreachable code

補充:方法的分類:按照是否有形參及返回值
請?zhí)砑訄D片描述
2、類比舉例
請?zhí)砑訄D片描述
、代碼示例:**


/*** 方法定義案例演示*/
public class MethodDefineDemo {/*** 無參無返回值方法的演示*/public void sayHello(){System.out.println("hello");}/*** 有參無返回值方法的演示* @param length int 第一個參數(shù),表示矩形的長* @param width int 第二個參數(shù),表示矩形的寬* @param sign char 第三個參數(shù),表示填充矩形圖形的符號*/public void printRectangle(int length, int width, char sign){for (int i = 1; i <= length ; i++) {for(int j=1; j <= width; j++){System.out.print(sign);}System.out.println();}}/*** 無參有返回值方法的演示* @return*/public int getIntBetweenOneToHundred(){return (int)(Math.random()*100+1);}/*** 有參有返回值方法的演示* @param a int 第一個參數(shù),要比較大小的整數(shù)之一* @param b int 第二個參數(shù),要比較大小的整數(shù)之二* @return int 比較大小的兩個整數(shù)中較大者的值*/public int max(int a, int b){return a > b ? a : b;}
}

5.4 如何調(diào)用實例方法

方法通過方法名被調(diào)用,且只有被調(diào)用才會執(zhí)行。

1、方法調(diào)用語法格式

對象.方法名([實參列表])

2、示例

舉例1:


/*** 方法調(diào)用案例演示*/
public class MethodInvokeDemo {public static void main(String[] args) {//創(chuàng)建對象MethodDefineDemo md = new MethodDefineDemo();System.out.println("-----------------------方法調(diào)用演示-------------------------");//調(diào)用MethodDefineDemo類中無參無返回值的方法sayHellomd.sayHello();md.sayHello();md.sayHello();//調(diào)用一次,執(zhí)行一次,不調(diào)用不執(zhí)行System.out.println("------------------------------------------------");//調(diào)用MethodDefineDemo類中有參無返回值的方法printRectanglemd.printRectangle(5,10,'@');System.out.println("------------------------------------------------");//調(diào)用MethodDefineDemo類中無參有返回值的方法getIntBetweenOneToHundredmd.getIntBetweenOneToHundred();//語法沒問題,就是結(jié)果丟失int num = md.getIntBetweenOneToHundred();System.out.println("num = " + num);System.out.println(md.getIntBetweenOneToHundred());//上面的代碼調(diào)用了getIntBetweenOneToHundred三次,這個方法執(zhí)行了三次System.out.println("------------------------------------------------");//調(diào)用MethodDefineDemo類中有參有返回值的方法maxmd.max(3,6);//語法沒問題,就是結(jié)果丟失int bigger = md.max(5,6);System.out.println("bigger = " + bigger);System.out.println("8,3中較大者是:" + md.max(8,9));}
}

舉例2:

//1、創(chuàng)建Scanner的對象
Scanner input = new Scanner(System.in);//System.in默認(rèn)代表鍵盤輸入//2、提示輸入xx
System.out.print("請輸入一個整數(shù):"); //對象.非靜態(tài)方法(實參列表)//3、接收輸入內(nèi)容
int num = input.nextInt();  //對象.非靜態(tài)方法()

5.5 使用的注意點

(1)必須先聲明后使用,且方法必須定義在類的內(nèi)部

(2)調(diào)用一次就執(zhí)行一次,不調(diào)用不執(zhí)行。

(3)方法中可以調(diào)用類中的方法或?qū)傩?#xff0c;不可以在方法內(nèi)部定義方法。

正確示例:

{方法1(){}方法2(){}
}

錯誤示例:

{方法1(){方法2(){  //位置錯誤}}
}

5.6 關(guān)鍵字return的使用

  • return在方法中的作用:
    • 作用1:結(jié)束一個方法
    • 作用2:結(jié)束一個方法的同時,可以返回數(shù)據(jù)給方法的調(diào)用者
  • 注意點:在return關(guān)鍵字的直接后面不能聲明執(zhí)行語句

5.7 方法調(diào)用內(nèi)存分析

  • 方法沒有被調(diào)用的時候,都在方法區(qū)中的字節(jié)碼文件(.class)中存儲。

  • 方法被調(diào)用的時候,需要進(jìn)入到棧內(nèi)存中運行。方法每調(diào)用一次就會在棧中有一個入棧動作,即給當(dāng)前方法開辟一塊獨立的內(nèi)存區(qū)域,用于存儲當(dāng)前方法的局部變量的值。

  • 當(dāng)方法執(zhí)行結(jié)束后,會釋放該內(nèi)存,稱為出棧,如果方法有返回值,就會把結(jié)果返回調(diào)用處,如果沒有返回值,就直接結(jié)束,回到調(diào)用處繼續(xù)執(zhí)行下一條指令。

  • 棧結(jié)構(gòu):先進(jìn)后出,后進(jìn)先出。

舉例分析:

public class Person {public static void main(String[] args) {Person p1 = new Person();p1.eat();}public static void eat() {sleep();System.out.println("人:吃飯");}public static void sleep(){System.out.println("人:睡覺");doSport();}public static void doSport(){System.out.println("人:運動");}
}

內(nèi)存分析:

請?zhí)砑訄D片描述

6. 對象數(shù)組

數(shù)組的元素可以是基本數(shù)據(jù)類型,也可以是引用數(shù)據(jù)類型。當(dāng)元素是引用類型中的類時,我們稱為對象數(shù)組。

1、案例

定義類Student,包含三個屬性:學(xué)號number(int),年級state(int),成績score(int)。 創(chuàng)建20個學(xué)生對象,學(xué)號為1到20,年級和成績都由隨機數(shù)確定。

問題一:打印出3年級(state值為3)的學(xué)生信息。

問題二:使用冒泡排序按學(xué)生成績排序,并遍歷所有學(xué)生信息

提示:

  1. 生成隨機數(shù):Math.random(),返回值類型double;

  2. 四舍五入取整:Math.round(double d),返回值類型long。

/** 定義類Student,包含三個屬性:學(xué)號number(int),年級state(int),成績score(int)。*/
public class Student {int number;//學(xué)號int state;//年級int score;//成績public void info(){System.out.println("number : " + number + ",state : " + state + ",score : " + score);}}
public class StudentTest {public static void main(String[] args) {// Student s1 = new Student();// s1.number = 1;// s1.state = (int)(Math.random() * 6 + 1);//[1,6]// s1.score = (int)(Math.random() * 101);//[0,100]//// Student s2 = new Student();// s2.number = 2;// s2.state = (int)(Math.random() * 6 + 1);//[1,6]// s2.score = (int)(Math.random() * 101);//[0,100]//// //....// 對象數(shù)組// String[] arr = new String[10];// 數(shù)組的創(chuàng)建Student[] students = new Student[20];// 通過循環(huán)結(jié)構(gòu)給數(shù)組的屬性賦值for (int i = 0; i < students.length; i++) {// 數(shù)組元素的賦值students[i] = new Student();// 數(shù)組元素是一個對象,給對象的各個屬性賦值students[i].number = (i + 1);students[i].state = (int) (Math.random() * 6 + 1);// [1,6]students[i].score = (int) (Math.random() * 101);// [0,100]}// 問題一:打印出3年級(state值為3)的學(xué)生信息。for (int i = 0; i < students.length; i++) {if (students[i].state == 3) {
//				System.out.println(
//						"number:" + students[i].number + ",state:" + students[i].state + ",score:" + students[i].score);students[i].info();}}System.out.println("******************************");// 問題二:使用冒泡排序按學(xué)生成績排序,并遍歷所有學(xué)生信息// 排序前for (int i = 0; i < students.length; i++) {
//			System.out.println(
//					"number:" + students[i].number + ",state:" + 
//							students[i].state + ",score:" + students[i].score);students[i].info();}System.out.println();// 排序:for (int i = 0; i < students.length - 1; i++) {for (int j = 0; j < students.length - 1 - i; j++) {if (students[j].score > students[j + 1].score) {Student temp = students[j];students[j] = students[j + 1];students[j + 1] = temp;}}}// 排序后:for (int i = 0; i < students.length; i++) {
//			System.out.println(
//					"number:" + students[i].number + ",state:" + 
//							students[i].state + ",score:" + students[i].score);students[i].info();}}}

內(nèi)存解析:
在這里插入圖片描述
2、注意點

對象數(shù)組,首先要創(chuàng)建數(shù)組對象本身,即確定數(shù)組的長度,然后再創(chuàng)建每一個元素對象,如果不創(chuàng)建,數(shù)組的元素的默認(rèn)值就是null,所以很容易出現(xiàn)空指針異常NullPointerException。

3、練習(xí)

(1)定義矩形類Rectangle,包含長、寬屬性,area()返回矩形面積的方法,perimeter()返回矩形周長的方法,String getInfo()返回圓對象的詳細(xì)信息(如:長、寬、面積、周長等數(shù)據(jù))的方法

(2)在測試類中創(chuàng)建長度為3的Rectangle[]數(shù)組,用來裝3個矩形對象,并給3個矩形對象的長分別賦值為10,20,30,寬分別賦值為5,15,25,遍歷輸出


public class Rectangle {double length;double width;public double area(){//面積return length * width;}public double perimeter(){//周長return 2 * (length + width);}public String getInfo(){return "長:" + length +",寬:" + width +",面積:" + area() +",周長:" + perimeter();}
}

public class ObjectArrayTest {public static void main(String[] args) {//聲明并創(chuàng)建一個長度為3的矩形對象數(shù)組Rectangle[] array = new Rectangle[3];//創(chuàng)建3個矩形對象,并為對象的實例變量賦值,//3個矩形對象的長分別是10,20,30//3個矩形對象的寬分別是5,15,25//調(diào)用矩形對象的getInfo()返回對象信息后輸出for (int i = 0; i < array.length; i++) {//創(chuàng)建矩形對象array[i] = new Rectangle();//為矩形對象的成員變量賦值array[i].length = (i+1) * 10;array[i].width = (2*i+1) * 5;//獲取并輸出對象對象的信息System.out.println(array[i].getInfo());}}
}

內(nèi)存解析:
請?zhí)砑訄D片描述

7. 再談方法

7.1 方法的重載(overload)

7.1.1 概念及特點

  • 方法重載:在同一個類中,允許存在一個以上的同名方法,只要它們的參數(shù)列表不同即可。
    • 參數(shù)列表不同,意味著參數(shù)個數(shù)或參數(shù)類型的不同
  • 重載的特點:與修飾符、返回值類型無關(guān),只看參數(shù)列表,且參數(shù)列表必須不同。(參數(shù)個數(shù)或參數(shù)類型)。調(diào)用時,根據(jù)方法參數(shù)列表的不同來區(qū)別。
  • 重載方法調(diào)用:JVM通過方法的參數(shù)列表,調(diào)用匹配的方法。
    • 先找個數(shù)、類型最匹配的
    • 再找個數(shù)和類型可以兼容的,如果同時多個方法可以兼容將會報錯

7.1.2 示例

舉例1:

//System.out.println()方法就是典型的重載方法,其內(nèi)部的聲明形式如下:
public class PrintStream {public void println(byte x)public void println(short x)public void println(int x)public void println(long x)public void println(float x)public void println(double x)public void println(char x)public void println(double x)public void println()}public class HelloWorld{public static void main(String[] args) {System.out.println(3);System.out.println(1.2f);System.out.println("hello!");}
}

? 舉例2:

//返回兩個整數(shù)的和
public int add(int x,int y){return x+y;
}//返回三個整數(shù)的和
public int add(int x,int y,int z){return x+y+z;
}
//返回兩個小數(shù)的和
public double add(double x,double y){return x+y;
}

? 舉例3:方法的重載和返回值類型無關(guān)

public class MathTools {//以下方法不是重載,會報錯public int getOneToHundred(){return (int)(Math.random()*100);}public double getOneToHundred(){return Math.random()*100;}
}

7.1.3 練習(xí)

**練習(xí)1:**判 斷與void show(int a,char b,double c){}構(gòu)成重載的有:

a)void show(int x,char y,double z){}     // nob)int show(int a,double c,char b){}      // yesc) void show(int a,double c,char b){}    // yesd) boolean show(int c,char b){}          // yese) void show(double c){}                 // yesf) double show(int x,char y,double z){}  // nog) void shows(){double c}                // no

練習(xí)2:編寫程序,定義三個重載方法并調(diào)用。

  • 方法名為mOL。

  • 三個方法分別接收一個int參數(shù)、兩個int參數(shù)、一個字符串參數(shù)。分別執(zhí)行平方運算并輸出結(jié)果,相乘并輸出結(jié)果,輸出字符串信息。

  • 在主類的main ()方法中分別用參數(shù)區(qū)別調(diào)用三個方法。

練習(xí)3:定義三個重載方法max(),第一個方法求兩個int值中的最大值,第二個方法求兩個double值中的最大值,第三個方法求三個double值中的最大值,并分別調(diào)用三個方法。

7.2 可變個數(shù)的形參

在**JDK 5.0 中提供了Varargs(variable number of arguments)**機制。即當(dāng)定義一個方法時,形參的類型可以確定,但是形參的個數(shù)不確定,那么可以考慮使用可變個數(shù)的形參。

格式:

方法名(參數(shù)的類型名 ...參數(shù)名)

舉例:

//JDK 5.0以前:采用數(shù)組形參來定義方法,傳入多個同一類型變量
public static void test(int a ,String[] books);//JDK5.0:采用可變個數(shù)形參來定義方法,傳入多個同一類型變量
public static void test(int a ,String...books);

特點:

  1. 可變參數(shù):方法參數(shù)部分指定類型的參數(shù)個數(shù)是可變多個:0個,1個或多個

  2. 可變個數(shù)形參的方法與同名的方法之間,彼此構(gòu)成重載

  3. 可變參數(shù)方法的使用與方法參數(shù)部分使用數(shù)組是一致的,二者不能同時聲明,否則報錯。

  4. 方法的參數(shù)部分有可變形參,需要放在形參聲明的最后

  5. 在一個方法的形參中,最多只能聲明一個可變個數(shù)的形參

案例分析:

案例1:n個字符串進(jìn)行拼接,每一個字符串之間使用某字符進(jìn)行分割,如果沒有傳入字符串,那么返回空字符串""

public class StringTools {String concat(char seperator, String... args){String str = "";for (int i = 0; i < args.length; i++) {if(i==0){str += args[i];}else{str += seperator + args[i];}}return str;}
}

public class StringToolsTest {public static void main(String[] args) {StringTools tools = new StringTools();System.out.println(tools.concat('-'));System.out.println(tools.concat('-',"hello"));System.out.println(tools.concat('-',"hello","world"));System.out.println(tools.concat('-',"hello","world","java"));}
}

案例2:求n個整數(shù)的和

public class NumberTools {public int total(int[] nums){int sum = 0;for (int i = 0; i < nums.length; i++) {sum += nums[i];}return sum;}public int sum(int... nums){int sum = 0;for (int i = 0; i < nums.length; i++) {sum += nums[i];}return sum;}
}
public class TestVarParam {public static void main(String[] args) {NumberTools tools = new NumberTools();System.out.println(tools.sum());//0個實參System.out.println(tools.sum(5));//1個實參System.out.println(tools.sum(5,6,2,4));//4個實參System.out.println(tools.sum(new int[]{5,6,2,4}));//傳入數(shù)組實參System.out.println("------------------------------------");System.out.println(tools.total(new int[]{}));//0個元素的數(shù)組System.out.println(tools.total(new int[]{5}));//1個元素的數(shù)組System.out.println(tools.total(new int[]{5,6,2,4}));//傳入數(shù)組實參}
}

案例3:如下的方法彼此構(gòu)成重載

public class MathTools {//求兩個整數(shù)的最大值public int max(int a,int b){return a>b?a:b;}//求兩個小數(shù)的最大值public double max(double a, double b){return a>b?a:b;}//求三個整數(shù)的最大值public int max(int a, int b, int c){return max(max(a,b),c);}//求n個整數(shù)的最大值public int max(int... nums){int max = nums[0];//如果沒有傳入整數(shù),或者傳入null,這句代碼會報異常for (int i = 1; i < nums.length; i++) {if(nums[i] > max){max = nums[i];}}return max;}/*    //求n整數(shù)的最大值public int max(int[] nums){  //編譯就報錯,與(int... nums)無法區(qū)分int max = nums[0];//如果沒有傳入整數(shù),或者傳入null,這句代碼會報異常for (int i = 1; i < nums.length; i++) {if(nums[i] > max){max = nums[i];}}return max;}*//*    //求n整數(shù)的最大值public int max(int first, int... nums){  //當(dāng)前類不報錯,但是調(diào)用時會引起多個方法同時匹配int max = first;for (int i = 0; i < nums.length; i++) {if(nums[i] > max){max = nums[i];}}return max;}*/
}

7.3 方法的參數(shù)傳遞機制

7.3.1 形參和實參

  • 形參(formal parameter):在定義方法時,方法名后面括號()中聲明的變量稱為形式參數(shù),簡稱形參。
  • 實參(actual parameter):在調(diào)用方法時,方法名后面括號()中的使用的值/變量/表達(dá)式稱為實際參數(shù),簡稱實參。

7.3.2 參數(shù)傳遞機制:值傳遞

Java里方法的參數(shù)傳遞方式只有一種:值傳遞。 即將實際參數(shù)值的副本(復(fù)制品)傳入方法內(nèi),而參數(shù)本身不受影響。

  • 形參是基本數(shù)據(jù)類型:將實參基本數(shù)據(jù)類型變量的“數(shù)據(jù)值”傳遞給形參

  • 形參是引用數(shù)據(jù)類型:將實參引用數(shù)據(jù)類型變量的“地址值”傳遞給形參

7.3.3 舉例

1、形參是基本數(shù)據(jù)類型

案例:編寫方法,交換兩個整型變量的值

public class Test {public static void main(String[] args) {int m = 10;int n = 20;System.out.println("m = " + m + ", n = " + n);//交換m和n的值
//		int temp = m;
//		m = n;
//		n = temp;ValueTransferTest1 test = new ValueTransferTest1();test.swap(m, n);System.out.println("m = " + m + ", n = " + n);}public void swap(int m,int n){int temp = m;m = n;n = temp;}}

內(nèi)存解析:請?zhí)砑訄D片描述

2、形參是引用數(shù)據(jù)類型

public class Test {public static void main(String[] args) {Data d1 = new Data();d1.m = 10;d1.n = 20;System.out.println("m = " + d1.m + ", n = " + d1.n);//實現(xiàn) 換序ValueTransferTest2 test = new ValueTransferTest2();test.swap(d1);System.out.println("m = " + d1.m + ", n = " + d1.n);}public void swap(Data data){int temp = data.m;data.m = data.n;data.n = temp;}
}
class Data{int m;int n;
}

內(nèi)存解析:
請?zhí)砑訄D片描述

7.3.4 練習(xí)

練習(xí)1:判斷如下程序輸出的結(jié)果

public class AssignNewObject {public void swap(MyData my){my = new MyData(); //考慮堆空間此新創(chuàng)建的對象,和main中的data對象是否有關(guān)int temp = my.x;my.x = my.y;my.y = temp;}public static void main(String[] args) {AssignNewObject tools = new AssignNewObject();MyData data = new MyData();data.x = 1;data.y = 2;System.out.println("交換之前:x = " + data.x +",y = " + data.y);//tools.swap(data);//調(diào)用完之后,x與y的值交換?System.out.println("交換之后:x = " + data.x +",y = " + data.y);//}
}class MyData{int x ;int y;
}

練習(xí)2:如下操作是否可以實現(xiàn)數(shù)組排序

public class ArrayTypeParam {//冒泡排序,實現(xiàn)數(shù)組從小到大排序public void sort(int[] arr){for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - 1 - i; j++) {if(arr[j] > arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}//打印數(shù)組的元素public void print(int[] arr){for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}System.out.println();}public static void main(String[] args) {ArrayTypeParam tools = new ArrayTypeParam();int[] nums = {4,3,1,6,7};System.out.println("排序之前:");tools.print(nums);tools.sort(nums);//對nums數(shù)組進(jìn)行排序System.out.println("排序之后:");tools.print(nums);//輸出nums數(shù)組的元素}
}

練習(xí)3:通過內(nèi)存結(jié)構(gòu)圖,寫出如下程序的輸出結(jié)果

//棧:每個方法在調(diào)用時,都會有以棧幀的方法壓入棧中。棧幀中保存了當(dāng)前方法中聲明的變量:方法內(nèi)聲明的,形參
//堆:存放new出來的"東西":對象(成員變量在對象中)、數(shù)組實體(數(shù)組元素)。 
//注意:變量前如果聲明有類型,那么這就是一個新的剛要定義的變量。如果變量前沒有聲明類型,那就說明此變量在之前已經(jīng)聲明過。
public class TransferTest3 {public static void main(String args[]) {TransferTest3 test = new TransferTest3();test.first();}public void first() {int i = 5;Value v = new Value();v.i = 25;second(v, i);System.out.println(v.i);}public void second(Value v, int i) {i = 0;v.i = 20;Value val = new Value();v = val;System.out.println(v.i + " " + i);}
}class Value {int i = 15;
}

內(nèi)存解析:
請?zhí)砑訄D片描述
練習(xí)4:貌似是考查方法的參數(shù)傳遞請?zhí)砑訄D片描述

//法一:public static void method(int a, int b) {// 在不改變原本題目的前提下,如何寫這個函數(shù)才能在main函數(shù)中輸出a=100,b=200? a = a * 10;b = b * 20;System.out.println(a);System.out.println(b);System.exit(0);}//法二:public static void method(int a, int b) {PrintStream ps = new PrintStream(System.out) {@Overridepublic void println(String x) {if ("a=10".equals(x)) {x = "a=100";} else if ("b=10".equals(x)) {x = "b=200";}super.println(x);}};System.setOut(ps);}

練習(xí)5:將對象作為參數(shù)傳遞給方法

(1)定義一個Circle類,包含一個double型的radius屬性代表圓的半徑,一個findArea()方法返回圓的面積。
(2)定義一個類PassObject,在類中定義一個方法printAreas(),該方法的定義如下:public void printAreas(Circle c, int time),在printAreas方法中打印輸出1到time之間的每個整數(shù)半徑值,以及對應(yīng)的面積。例如,times為5,則輸出半徑1,2,3,4,5,以及對應(yīng)的圓面積。
(3)在main方法中調(diào)用printAreas()方法,調(diào)用完畢后輸出當(dāng)前半徑值。程序運行結(jié)果如圖所示。
請?zhí)砑訄D片描述

7.4 遞歸(recursion)方法

舉例1:
請?zhí)砑訄D片描述
舉例2:

從前有座山,山上有座廟,廟里有個老和尚,老和尚在給小和尚講故事,講的啥?從前有座山,山上有座廟,廟里有個老和尚,老和尚在給小和尚講故事,講的啥?從前有座山,山上有座廟,廟里有個老和尚,老和尚在給小和尚講故事,講的啥?從前有座山,山上有座廟,廟里有個老和尚,老和尚在給小和尚講故事,講的啥?......
老和尚沒了,廟塌了,小和尚還俗結(jié)婚了。

遞歸方法調(diào)用:方法自己調(diào)用自己的現(xiàn)象就稱為遞歸。

**遞歸的分類:**直接遞歸、間接遞歸。

  • 直接遞歸:方法自身調(diào)用自己。

    public void methodA(){methodA();
    }
    
  • 間接遞歸:可以理解為A()方法調(diào)用B()方法,B()方法調(diào)用C()方法,C()方法調(diào)用A()方法。

    public static void A(){B();
    }public static void B(){C();
    }public static void C(){A();
    }
    

說明

  • 遞歸方法包含了一種隱式的循環(huán)。
  • 遞歸方法會重復(fù)執(zhí)行某段代碼,但這種重復(fù)執(zhí)行無須循環(huán)控制。
  • 遞歸一定要向已知方向遞歸,否則這種遞歸就變成了無窮遞歸,停不下來,類似于死循環(huán)。最終發(fā)生棧內(nèi)存溢出。

舉例:

舉例1:計算1 ~ n的和

public class RecursionDemo {public static void main(String[] args) {RecursionDemo demo = new RecursionDemo();//計算1~num的和,使用遞歸完成int num = 5;// 調(diào)用求和的方法int sum = demo.getSum(num);// 輸出結(jié)果System.out.println(sum);}/*通過遞歸算法實現(xiàn).參數(shù)列表:int 返回值類型: int */public int getSum(int num) {/* num為1時,方法返回1,相當(dāng)于是方法的出口,num總有是1的情況*/if(num == 1){return 1;}/*num不為1時,方法返回 num +(num-1)的累和遞歸調(diào)用getSum方法*/return num + getSum(num-1);}
}

代碼執(zhí)行圖解:
請?zhí)砑訄D片描述
舉例2:遞歸方法計算n!

public int multiply(int num){if(num == 1){return 1;}else{return num * multiply(num - 1);}
}

請?zhí)砑訄D片描述
舉例3:已知有一個數(shù)列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),其中n是大于0的整數(shù),求f(10)的值。

public int f(int num){if(num == 0){return 1;}else if(num == 1){return 4;}else{return 2 * f(num - 1) + f(num - 2);}
}

舉例4:已知一個數(shù)列:f(20) = 1,f(21) = 4,f(n+2) = 2*f(n+1)+f(n),其中n是大于0的整數(shù),求f(10)的值。

public int func(int num){if(num == 20){return 1;}else if(num == 21){return 4;}else{return func(num + 2) - 2 * func(num + 1);}
}

舉例5:計算斐波那契數(shù)列(Fibonacci)的第n個值,斐波那契數(shù)列滿足如下規(guī)律,

1,1,2,3,5,8,13,21,34,55,....

即從第三個數(shù)開始,一個數(shù)等于前兩個數(shù)之和。假設(shè)f(n)代表斐波那契數(shù)列的第n個值,那么f(n)滿足:
f(n) = f(n-2) + f(n-1);

	//使用遞歸的寫法int f(int n) {//計算斐波那契數(shù)列第n個值是多少if (n < 1) {//負(fù)數(shù)是返回特殊值1,表示不計算負(fù)數(shù)情況return 1;}if (n == 1 || n == 2) {return 1;}return f(n - 2) + f(n - 1);}//不用遞歸int fValue(int n) {//計算斐波那契數(shù)列第n個值是多少if (n < 1) {//負(fù)數(shù)是返回特殊值1,表示不計算負(fù)數(shù)情況return 1;}if (n == 1 || n == 2) {return 1;}//從第三個數(shù)開始,  等于 前兩個整數(shù)相加int beforeBefore = 1; //相當(dāng)于n=1時的值int before = 1;//相當(dāng)于n=2時的值int current = beforeBefore + before; //相當(dāng)于n=3的值//再完后for (int i = 4; i <= n; i++) {beforeBefore = before;before = current;current = beforeBefore + before;/*假設(shè)i=4beforeBefore = before; //相當(dāng)于n=2時的值before = current; //相當(dāng)于n=3的值current = beforeBefore + before; //相當(dāng)于n = 4的值假設(shè)i=5beforeBefore = before; //相當(dāng)于n=3的值before = current; //相當(dāng)于n = 4的值current = beforeBefore + before; //相當(dāng)于n = 5的值....*/}return current;}

8. 關(guān)鍵字:package、import

8.1 package(包)

package,稱為包,用于指明該文件中定義的類、接口等結(jié)構(gòu)所在的包。

8.1.1 語法格式

package 頂層包名.子包名 ;

舉例:pack1\pack2\PackageTest.java

package pack1.pack2;    //指定類PackageTest屬于包pack1.pack2public class PackageTest{public void display(){System.out.println("in  method display()");}
}

說明:

  • 一個源文件只能有一個聲明包的package語句
  • package語句作為Java源文件的第一條語句出現(xiàn)。若缺省該語句,則指定為無名包。
  • 包名,屬于標(biāo)識符,滿足標(biāo)識符命名的規(guī)則和規(guī)范(全部小寫)、見名知意
    • 包通常使用所在公司域名的倒置:com.atguigu.xxx。
    • 大家取包名時不要使用"java.xx"包
  • 包對應(yīng)于文件系統(tǒng)的目錄,package語句中用 “.” 來指明包(目錄)的層次,每.一次就表示一層文件目錄。
  • 同一個包下可以聲明多個結(jié)構(gòu)(類、接口),但是不能定義同名的結(jié)構(gòu)(類、接口)。不同的包下可以定義同名的結(jié)構(gòu)(類、接口)

8.1.2 包的作用

  • 包可以包含類和子包,劃分項目層次,便于管理
  • 幫助管理大型軟件系統(tǒng):將功能相近的類劃分到同一個包中。比如:MVC的設(shè)計模式
  • 解決類命名沖突的問題
  • 控制訪問權(quán)限

8.1.3 應(yīng)用舉例

舉例1:某航運軟件系統(tǒng)包括:一組域?qū)ο?、GUI和reports子系統(tǒng)

請?zhí)砑訄D片描述
舉例2:MVC設(shè)計模式

MVC是一種軟件構(gòu)件模式,目的是為了降低程序開發(fā)中代碼業(yè)務(wù)的耦合度。

MVC設(shè)計模式將整個程序分為三個層次:視圖模型(Viewer)層控制器(Controller)層,與數(shù)據(jù)模型(Model)層。這種將程序輸入輸出、數(shù)據(jù)處理,以及數(shù)據(jù)的展示分離開來的設(shè)計模式使程序結(jié)構(gòu)變的靈活而且清晰,同時也描述了程序各個對象間的通信方式,降低了程序的耦合性。

視圖層viewer:顯示數(shù)據(jù),為用戶提供使用界面,與用戶直接進(jìn)行交互。>相關(guān)工具類   view.utils>自定義view  view.ui控制層controller:解析用戶請求,處理業(yè)務(wù)邏輯,給予用戶響應(yīng)>應(yīng)用界面相關(guān)    controller.activity>存放fragment   controller.fragment>顯示列表的適配器 controller.adapter>服務(wù)相關(guān)的        controller.service>抽取的基類        controller.base模型層model:主要承載數(shù)據(jù)、處理數(shù)據(jù)>數(shù)據(jù)對象封裝 model.bean/domain>數(shù)據(jù)庫操作類 model.dao>數(shù)據(jù)庫      model.db

請?zhí)砑訄D片描述

8.1.4 JDK中主要的包介紹

java.lang----包含一些Java語言的核心類,如String、Math、Integer、 System和Thread,提供常用功能
java.net----包含執(zhí)行與網(wǎng)絡(luò)相關(guān)的操作的類和接口。
java.io ----包含能提供多種輸入/輸出功能的類。
java.util----包含一些實用工具類,如定義系統(tǒng)特性、接口的集合框架類、使用與日期日歷相關(guān)的函數(shù)。
java.text----包含了一些java格式化相關(guān)的類
java.sql----包含了java進(jìn)行JDBC數(shù)據(jù)庫編程的相關(guān)類/接口
java.awt----包含了構(gòu)成抽象窗口工具集(abstract window toolkits)的多個類,這些類被用來構(gòu)建和管理應(yīng)用程序的圖形用戶界面(GUI)。

8.2 import(導(dǎo)入)

為了使用定義在其它包中的Java類,需用import語句來顯式引入指定包下所需要的類。相當(dāng)于import語句告訴編譯器到哪里去尋找這個類。

8.2.1 語法格式

import 包名.類名;

8.2.2 應(yīng)用舉例

import pack1.pack2.Test;   //import pack1.pack2.*;表示引入pack1.pack2包中的所有結(jié)構(gòu)public class PackTest{public static void main(String args[]){Test t = new Test();          //Test類在pack1.pack2包中定義t.display();}
}

8.2.3 注意事項

  • import語句,聲明在包的聲明和類的聲明之間。

  • 如果需要導(dǎo)入多個類或接口,那么就并列顯式多個import語句即可

  • 如果使用a.*導(dǎo)入結(jié)構(gòu),表示可以導(dǎo)入a包下的所有的結(jié)構(gòu)。舉例:可以使用java.util.*的方式,一次性導(dǎo)入util包下所有的類或接口。

  • 如果導(dǎo)入的類或接口是java.lang包下的,或者是當(dāng)前包下的,則可以省略此import語句。

  • 如果已經(jīng)導(dǎo)入java.a包下的類,那么如果需要使用a包的子包下的類的話,仍然需要導(dǎo)入。

  • 如果在代碼中使用不同包下的同名的類,那么就需要使用類的全類名的方式指明調(diào)用的是哪個類。

  • (了解)import static組合的使用:調(diào)用指定類或接口下的靜態(tài)的屬性或方法

9. 面向?qū)ο筇卣饕?#xff1a;封裝性(encapsulation)

9.1 為什么需要封裝?

  • 我要用洗衣機,只需要按一下開關(guān)和洗滌模式就可以了。有必要了解洗衣機內(nèi)部的結(jié)構(gòu)嗎?有必要碰電動機嗎?
  • 我要開車,我不需要懂離合、油門、制動等原理和維修也可以駕駛。
  • 客觀世界里每一個事物的內(nèi)部信息都隱藏在其內(nèi)部,外界無法直接操作和修改,只能通過指定的方式進(jìn)行訪問和修改。

隨著我們系統(tǒng)越來越復(fù)雜,類會越來越多,那么類之間的訪問邊界必須把握好,面向?qū)ο蟮拈_發(fā)原則要遵循“高內(nèi)聚、低耦合”。

高內(nèi)聚、低耦合是軟件工程中的概念,也是UNIX 操作系統(tǒng)設(shè)計的經(jīng)典原則。

內(nèi)聚,指一個模塊內(nèi)各個元素彼此結(jié)合的緊密程度;耦合指一個軟件結(jié)構(gòu)內(nèi)不同模塊之間互連程度的度量。內(nèi)聚意味著重用和獨立,耦合意味著多米諾效應(yīng)牽一發(fā)動全身。

而“高內(nèi)聚,低耦合”的體現(xiàn)之一:

  • 高內(nèi)聚:類的內(nèi)部數(shù)據(jù)操作細(xì)節(jié)自己完成,不允許外部干涉;
  • 低耦合:僅暴露少量的方法給外部使用,盡量方便外部調(diào)用。

9.2 何為封裝性?

所謂封裝,就是把客觀事物封裝成抽象概念的類,并且類可以把自己的數(shù)據(jù)和方法只向可信的類或者對象開放,向沒必要開放的類或者對象隱藏信息。

通俗的講,把該隱藏的隱藏起來,該暴露的暴露出來。這就是封裝性的設(shè)計思想。

9.3 Java如何實現(xiàn)數(shù)據(jù)封裝

  • 實現(xiàn)封裝就是控制類或成員的可見性范圍。這就需要依賴訪問控制修飾符,也稱為權(quán)限修飾符來控制。

  • 權(quán)限修飾符:public、protected、缺省private。具體訪問范圍如下:

修飾符本類內(nèi)部本包內(nèi)其他包的子類其他包非子類
private×××
缺省××
protected×
public
  • 具體修飾的結(jié)構(gòu):
    • 外部類:public、缺省
    • 成員變量、成員方法、構(gòu)造器、成員內(nèi)部類:public、protected、缺省、private

請?zhí)砑訄D片描述
請?zhí)砑訄D片描述

9.4 封裝性的體現(xiàn)

9.4.1 成員變量/屬性私有化

概述:私有化類的成員變量,提供公共的get和set方法,對外暴露獲取和修改屬性的功能。

實現(xiàn)步驟:

使用 private 修飾成員變量

private 數(shù)據(jù)類型 變量名 ;

代碼如下:

public class Person {private String name;private int age;private boolean marry;
}

提供 getXxx方法 / setXxx 方法,可以訪問成員變量,代碼如下:

public class Person {private String name;private int age;private boolean marry;public void setName(String n) {name = n;}public String getName() {return name;}public void setAge(int a) {age = a;}public int getAge() {return age;}public void setMarry(boolean m){marry = m;}public boolean isMarry(){return marry;}
}

測試:

public class PersonTest {public static void main(String[] args) {Person p = new Person();//實例變量私有化,跨類是無法直接使用的/* p.name = "張三";p.age = 23;p.marry = true;*/p.setName("張三");System.out.println("p.name = " + p.getName());p.setAge(23);System.out.println("p.age = " + p.getAge());p.setMarry(true);System.out.println("p.marry = " + p.isMarry());}
}

成員變量封裝的好處:

  • 讓使用者只能通過事先預(yù)定的方法來訪問數(shù)據(jù),從而可以在該方法里面加入控制邏輯,限制對成員變量的不合理訪問。還可以進(jìn)行數(shù)據(jù)檢查,從而有利于保證對象信息的完整性。
  • 便于修改,提高代碼的可維護(hù)性。主要說的是隱藏的部分,在內(nèi)部修改了,如果其對外可以的訪問方式不變的話,外部根本感覺不到它的修改。例如:Java8->Java9,String從char[]轉(zhuǎn)為byte[]內(nèi)部實現(xiàn),而對外的方法不變,我們使用者根本感覺不到它內(nèi)部的修改。

開心一笑:

A man and woman are in a computer programming lecture. The man touches the woman's breasts."Hey!" she says. "Those are private!"The man says, "But we're in the same class!"

9.4.2 私有化方法

public class ArrayUtil {public int max(int[] arr) {int maxValue = arr[0];for(int i = 1;i < arr.length;i++){if(maxValue < arr[i]){maxValue = arr[i];}}return maxValue;}public int min(int[] arr){int minValue = arr[0];for(int i = 1;i < arr.length;i++){if(minValue > arr[i]){minValue = arr[i];}}return minValue;}public int sum(int[] arr) {int sum = 0;for(int i = 0;i < arr.length;i++){sum += arr[i];}return sum;}public int avg(int[] arr) {int sumValue = sum(arr);return sumValue / arr.length;}// 創(chuàng)建一系列重載的上述方法// public double max(double[] arr){}// public float max(float[] arr){}// public byte max(byte[] arr){}public void print(int[] arr) {for(int i = 0;i < arr.length;i++){System.out.print(arr[i] + "  ");}System.out.println();}public int[] copy(int[] arr) {int[] arr1 = new int[arr.length];for(int i = 0;i < arr.length;i++){arr1[i] = arr[i];}return arr1;}public void reverse(int[] arr) {for(int i = 0,j = arr.length - 1;i < j;i++,j--){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}public void sort(int[] arr,String desc) {if("ascend".equals(desc)){//if(desc.equals("ascend")){for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - 1 - i; j++) {if (arr[j] > arr[j + 1]) {
//						int temp = arr[j];
//						arr[j] = arr[j + 1];
//						arr[j + 1] = temp;swap(arr,j,j+1);}}}}else if ("descend".equals(desc)){for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - 1 - i; j++) {if (arr[j] < arr[j + 1]) {
//						int temp = arr[j];
//						arr[j] = arr[j + 1];
//						arr[j + 1] = temp;swap(arr,j,j+1);}}}}else{System.out.println("您輸入的排序方式有誤!");}}private void swap(int[] arr,int i,int j){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}public int getValue(int[] arr, int value) {//方法:線性查找for(int i = 0;i < arr.length;i++){if(value == arr[i]){return i;}}return - 1;}
}

注意:

開發(fā)中,一般成員實例變量都習(xí)慣使用private修飾,再提供相應(yīng)的public權(quán)限的get/set方法訪問。

對于final的實例變量,不提供set()方法。(后面final關(guān)鍵字的時候講)

對于static final的成員變量,習(xí)慣上使用public修飾。

10. 類的成員之三:構(gòu)造器(Constructor)

我們new完對象時,所有成員變量都是默認(rèn)值,如果我們需要賦別的值,需要挨個為它們再賦值,太麻煩了。我們能不能在new對象時,直接為當(dāng)前對象的某個或所有成員變量直接賦值呢?

可以,Java給我們提供了構(gòu)造器(Constructor),也稱為構(gòu)造方法。

10.1 構(gòu)造器的作用

new對象,并在new對象的時候為實例變量賦值。

舉例:Person p = new Person(“Peter”,15);

解釋:如同我們規(guī)定每個“人”一出生就必須先洗澡,我們就可以在“人”的構(gòu)造器中加入完成“洗澡”的程序代碼,于是每個“人”一出生就會自動完成“洗澡”,程序就不必再在每個人剛出生時一個一個地告訴他們要“洗澡”了。

10.2 構(gòu)造器的語法格式

[修飾符] class 類名{[修飾符] 構(gòu)造器名(){// 實例初始化代碼}[修飾符] 構(gòu)造器名(參數(shù)列表){// 實例初始化代碼}
}

說明:

  1. 構(gòu)造器名必須與它所在的類名必須相同。
  2. 它沒有返回值,所以不需要返回值類型,也不需要void。
  3. 構(gòu)造器的修飾符只能是權(quán)限修飾符,不能被其他任何修飾。比如,不能被static、final、synchronized、abstract、native修飾,不能有return語句返回值。

代碼如下:

public class Student {private String name;private int age;// 無參構(gòu)造public Student() {}// 有參構(gòu)造public Student(String n,int a) {name = n;age = a;}public String getName() {return name;}public void setName(String n) {name = n;}public int getAge() {return age;}public void setAge(int a) {age = a;}public String getInfo(){return "姓名:" + name +",年齡:" + age;}
}
public class TestStudent {public static void main(String[] args) {//調(diào)用無參構(gòu)造創(chuàng)建學(xué)生對象Student s1 = new Student();//調(diào)用有參構(gòu)造創(chuàng)建學(xué)生對象Student s2 = new Student("張三",23);System.out.println(s1.getInfo());System.out.println(s2.getInfo());}
}

10.3 使用說明

  1. 當(dāng)我們沒有顯式的聲明類中的構(gòu)造器時,系統(tǒng)會默認(rèn)提供一個無參的構(gòu)造器并且該構(gòu)造器的修飾符默認(rèn)與類的修飾符相同
  2. 當(dāng)我們顯式的定義類的構(gòu)造器以后,系統(tǒng)就不再提供默認(rèn)的無參的構(gòu)造器了。
  3. 在類中,至少會存在一個構(gòu)造器。
  4. 構(gòu)造器是可以重載的。

11. 階段性知識補充

11.1 類中屬性賦值過程

1、在類的屬性中,可以有哪些位置給屬性賦值?

① 默認(rèn)初始化

② 顯式初始化

③ 構(gòu)造器中初始化

④ 通過"對象.屬性"或"對象.方法"的方式,給屬性賦值

2、這些位置執(zhí)行的先后順序是怎樣?

順序:① - ② - ③ - ④

3、說明:

  • 上述中的①、②、③在對象創(chuàng)建過程中,只執(zhí)行一次。
  • ④ 是在對象創(chuàng)建后執(zhí)行的,可以根據(jù)需求多次執(zhí)行。

11.2 JavaBean

  • JavaBean是一種Java語言寫成的可重用組件。

    • 好比你做了一個扳手,這個扳手會在很多地方被拿去用。這個扳手也提供多種功能(你可以拿這個扳手扳、錘、撬等等),而這個扳手就是一個組件。
  • 所謂JavaBean,是指符合如下標(biāo)準(zhǔn)的Java類:

    • 類是公共的
    • 有一個無參的公共的構(gòu)造器
    • 有屬性,且有對應(yīng)的get、set方法
  • 用戶可以使用JavaBean將功能、處理、值、數(shù)據(jù)庫訪問和其他任何可以用Java代碼創(chuàng)造的對象進(jìn)行打包,并且其他的開發(fā)者可以通過內(nèi)部的JSP頁面、Servlet、其他JavaBean、applet程序或者應(yīng)用來使用這些對象。用戶可以認(rèn)為JavaBean提供了一種隨時隨地的復(fù)制和粘貼的功能,而不用關(guān)心任何改變。

  • 《Think in Java》中提到,JavaBean最初是為Java GUI的可視化編程實現(xiàn)的。你拖動IDE構(gòu)建工具創(chuàng)建一個GUI 組件(如多選框),其實是工具給你創(chuàng)建Java類,并提供將類的屬性暴露出來給你修改調(diào)整,將事件監(jiān)聽器暴露出來。

  • 示例

    public class JavaBean {private String name; // 屬性一般定義為privateprivate int age;public JavaBean() {}public int getAge() {return age;}public void setAge(int a) {age = a;}public String getName() {return name;}public void setName(String n) {name = n;}
    }

11.3 UML類圖

  • UML(Unified Modeling Language,統(tǒng)一建模語言),用來描述軟件模型架構(gòu)的圖形化語言。

  • 常用的UML工具軟件有PowerDesingerRoseEnterprise Architect。

  • UML工具軟件不僅可以繪制軟件開發(fā)中所需的各種圖表,還可以生成對應(yīng)的源代碼。

  • 在軟件開發(fā)中,使用UML類圖可以更加直觀地描述類內(nèi)部結(jié)構(gòu)(類的屬性和操作)以及類之間的關(guān)系(如關(guān)聯(lián)、依賴、聚合等)。

    • +表示 public 類型, - 表示 private 類型,#表示protected類型
    • 方法的寫法:
      方法的類型(+、-) 方法名(參數(shù)名: 參數(shù)類型):返回值類型
    • 斜體表示抽象方法或類。

請?zhí)砑訄D片描述
請?zhí)砑訄D片描述

http://www.risenshineclean.com/news/52706.html

相關(guān)文章:

  • 用手機域名做網(wǎng)站有多少大數(shù)據(jù)精準(zhǔn)獲客軟件
  • 有哪個網(wǎng)站能賣自己做的衣服信息推廣平臺
  • 快速免費做網(wǎng)站教育培訓(xùn)機構(gòu)有哪些
  • 做網(wǎng)站項目需要多少錢百度地圖推廣怎么做的
  • 做網(wǎng)站開發(fā)的有哪些公司好人工智能培訓(xùn)課程
  • 江蘇營銷型網(wǎng)站推廣網(wǎng)絡(luò)營銷組合策略
  • 洛陽網(wǎng)站建設(shè)哪家專業(yè)新聞源軟文推廣平臺
  • paypal綁定wordpressseo專業(yè)培訓(xùn)學(xué)費多少錢
  • 長沙網(wǎng)站優(yōu)化方式代推廣平臺
  • 四川個人網(wǎng)站備案百度地圖客服人工電話
  • 怎樣將自己做的網(wǎng)站發(fā)布到外網(wǎng)上二維碼推廣賺傭金平臺
  • 著名網(wǎng)站設(shè)計師廣告設(shè)計需要學(xué)什么
  • 如何通過axure做網(wǎng)站架構(gòu)信息流推廣方式
  • 秦皇島網(wǎng)站制作長尾關(guān)鍵詞挖掘工具愛網(wǎng)站
  • 做app還是做微網(wǎng)站好成都seo
  • 文章采集網(wǎng)站上海seo博客
  • 做網(wǎng)站都需要自己的服務(wù)器嗎熱搜詞排行榜
  • 網(wǎng)站背景如何做網(wǎng)站注冊
  • wordpress常常被用來做什么網(wǎng)站東莞新聞頭條新聞
  • 南昌 網(wǎng)站建設(shè)重慶seo網(wǎng)站排名
  • 有幾個網(wǎng)站如何做外貿(mào)鄭州千鋒教育培訓(xùn)機構(gòu)怎么樣
  • hbuilder網(wǎng)頁制作模板seo高手培訓(xùn)
  • 個人直播網(wǎng)站開發(fā)廣告安裝接單app
  • 農(nóng)八師建設(shè)兵團社保網(wǎng)站保定seo網(wǎng)站推廣
  • 全國住房和城鄉(xiāng)建設(shè)廳證書查詢網(wǎng)搜索引擎優(yōu)化面對哪些困境
  • 網(wǎng)站建設(shè)優(yōu)化公司哪家好公司頁面設(shè)計
  • 網(wǎng)站分類查詢百度競價推廣點擊軟件奔奔
  • 福州企業(yè)網(wǎng)站維護(hù)價格低seo整站優(yōu)化新站快速排名
  • 網(wǎng)站備案 有什么用品牌整合營銷案例
  • 做訂餐網(wǎng)站數(shù)據(jù)庫應(yīng)該有哪些表凡科建站怎么樣