傳統的開發程序的方式採用過程化的編程方式,即將程序考慮成一個順序執行的指令串。因此採用過程化開發方式的程序員首先要作的事,就是針對需求,自頂向下、逐步細化,將問題分解成一連串的簡單步驟。可是隨着用戶需求的不斷增長和變動,軟件規模愈來愈大,業務邏輯愈來愈複雜,傳統的這種面向過程的開發方式暴露出來許多問題,如軟件開發延遲,開發成本難以控制,工程難以維護等。java
在面向對象程序設計裏,將數據和處理數據的方法緊密地結合在一塊兒,造成類,再將類實例化,造成對象。計算機程序被概念化成協同工做、共同完成所需任務的一組對象集。每個對象都是程序的一個獨立部分,可自行控制並與其餘對象進行通訊和交互。程序員
對象,是理解面向對象技術的關鍵。在現實世界中,對象隨處可見,如寵物狗,桌子,自行車,樹、鳥、魚等。真實世界對象具備共同的兩個特性:它們都有狀態和行爲。狗有狀態(名字,顏色,品種,飢餓)和行爲(叫,刨地,搖尾巴),自行車也有狀態(當前的齒輪檔位,當前的速度)和行爲(變速,剎車)。編程
軟件中的對象在概念性上與真實世界中的對象很類似,它們都包括狀態和相關的行爲。一個對象在屬性(在一些程序設計語言中用變量表明)中存儲它的狀態,並經過方法(在一些程序設計語言中是函數)暴露它的行爲。函數
在現實世界中,會常常發現許多單獨的對象都是同一類型。例如,也許有成千上萬的單個的自行車存在,但它們都是一樣的模型,以相同的方式被製造。每個自行車都是構建於同一模板並所以包含一樣的組件。在面向對象術語中,就能夠說,某我的的具體的自行車是自行車這個對象類的一個實例。this
一個類就是一個模板,從它那裏個體對象被建立。由類構造對象的過程稱爲建立類的實例。設計
類是一組具備相同屬性和行爲的對象的抽象。而對象則是類的具體存在。因此,在面向對象的程序設計語言中,類表明一個對象類型,它就像一個模板同樣,在代碼運行階段它被建立爲一個個對象實例。每一個類由兩個部分組成:屬性和行爲。屬性一般是一些數據狀態值,類一般將數據封裝在本身內部,訪問這些數據屬性必須經過類公開的方法,或者接口。code
類的本質是一種自定義的數據類型,可使用類來定義變量,全部使用類定義的變量都是引用變量,它們將會引用到類的對象。對象
對於一個類而言,能夠包含三種最多見的成員:Field、方法和構造器。Field用於定義該類或該類的實例所包含的狀態數據;方法則用於定義該類或該類的實例的行爲特徵或者功能實現;構造器用於構造該類的實例。blog
類的聲明如如下代碼所示:遞歸
[類修飾符] class 類的名稱 [extends 父類名稱] [implements 接口名稱] { //屬性、構造函數和方法聲明 }
其中class關鍵字是必需的。類的名稱用來標識一個類,它的命名要符合Java標識符命名規範。在這裏,用方括號將類修飾符包圍起來,它表明的含義是裏面的內容是可選的。
在同一個Java源文件中能夠有多個類,但不能包含兩個或兩個以上的帶有public修飾詞的類。若是某個類的聲明前含有public修飾詞,那麼含有此類的源文件必須與此類的類名相同。
在聲明一個類時,還能夠提供更多的信息。例如,指明該類的父類(也稱爲超類)的名稱,即該類是從哪一個類派生過來的,這須要在類名後面加上關鍵字extends來實現。還能夠在聲明一個類時指明該類是否實現接口,這須要在類名後面加上關鍵字implements來實現。
類的主體簡稱類體,指的是類名後面大括號中的內容。類體包含全部用於建立自該類的對象的生命週期的代碼,包括構造器(用於初始化新對象)、屬性聲明(用於表示類及其對象的狀態)及方法(實現類及其對象的行爲)。
使用new關鍵字建立對象。
public class Hello{ public static void main(String[] args) { Hello h1 = new Hello();//建立Hello類的第一個對象 h.sayWorld(); Hello h2 = new Hello();//建立Hello類的第二個對象 h.sayWorld(); } public void sayWorld(){ System.out.println("Hello world!"); } }
一個類能夠有多個對象。若是建立了多個對象,則每一個對象都獨立的擁有一套類的屬性(非static修飾的),意味着,若是咱們修改一個對象的屬性a,則不影響另一個對象屬性a的值。
屬性的經常使用叫法:屬性=成員變量=field=域=字段。
在程序中有多種類型的變量,這些變量在程序中的位置不一樣,所起的做用也不相同。
分類以下:
參數和局部變量都是演草紙,方法執行完就清除了。
方法裏建立的對象是不會隨着方法結束被清除的。由於對象是實例,不是變量,對象被建立出來之後,被堆在一塊兒,放在相似公告板的地方,只要有引用指向一個對象,這個對象的數據就能夠經過這個引用來訪問。
成員變量在類加載時會有初始化值,局部變量在類加載時不會有初始化值,因此因此要使用局部變量時,必定要顯式的給它賦值。
方法的經常使用叫法:方法=成員方法=函數=method。
所謂方法,相似於其餘語言中的函數,是一個相對獨立的代碼語句塊,一般實現必定的功能。
方法的設計原則:方法的本意是功能塊,就是實現某個功能的語句塊的集合,咱們設計方法的時候,最好保持方法的原子性,就是一個方法只完成一個功能,這樣利於咱們後期的擴展。
在類中聲明成員方法的語法格式以下:
[修飾符] 方法返回值類型 方法名(形參列表) { //由零條到多條可執行性語句組成的方法體 }
一、無參數無返回值的方法
// 無參數無返回值的方法(若是方法沒有返回值,不能不寫,必須寫void,表示沒有返回值) public void f1() { System.out.println("無參數無返回值的方法"); }
二、有參數無返回值的方法
/** * 有參數無返回值的方法 * 參數列表由零組到多組「參數類型+形參名」組合而成,多組參數之間以英文逗號(,)隔開,形參類型和形參名之間以英文空格隔開 */ public void f2(int a, String b, int c) { System.out.println(a + "-->" + b + "-->" + c); }
三、有返回值無參數的方法
// 有返回值無參數的方法 (返回值能夠是任意的類型 ,在函數裏面必須有return關鍵字返回對應的類型) public int f3() { System.out.println("有返回值無參數的方法"); return 2; }
四、有返回值有參數的方法
// 有返回值有參數的方法 public int f4(int a, int b) { return a * b; }
五、return在無返回值方法的特殊使用
// return在無返回值方法的特殊使用 public void f5(int a) { if (a>10) { return;//表示結束所在方法 (f5方法)的執行,下方的輸出語句不會執行 } System.out.println(a); }
在同一個類中,方法之間的調用語法以下:
方法名( );
在不一樣的類之間,方法之間的調用語法以下:
對象名.函數名(實參列表)//方法調用要有括號,即便沒有參數
A方法調用B方法,咱們很容易理解。
遞歸就是A方法調用A方法,就是本身調用本身 。
利用遞歸能夠用簡單的程序來解決一些複雜的問題 ,它一般把一個大型複雜的問題層層轉化爲一個於原問題類似的規模較小的問題來求解,遞歸策略只需少許的程序就可描述出解題過程所須要的屢次重複計算,大大的減小了程序的代碼量。遞歸的能力在於用有限的語句來定義對象的無限集合。
遞歸結構包括兩個部分:
遞歸頭:何時不調用自身方法。若是沒有頭,將陷入死循環;
遞歸體:何時須要調用自身方法。
public class Variable { public static void main(String[] args) { System.out.println(new Variable().f(3)); } //5! 5*4*3*2*1 public static int f(int n){ if(n==1){ return 1; }else { return n*f(n-1); } } }
方法重載指在同一個類裏面,有多個名字相同的方法,可是方法的參數類型或者參數的個數不一致,稱之爲方法重載,方法的返回類型不做爲方法重載判斷的依據。方法重載以後,具體要調用哪一個重載的方法,由方法的參數類型或個數決定(自動匹配)。
JDK1.5開始,Java支持傳遞同類型的可變參數給一個方法。
在方法聲明中,在指定參數類型後加一個省略號(...)。
一個方法中只能指定一個可變參數,它必須是方法的最後一個參數。任何普通的參數必須在它以前聲明。
public class Variable { public static void main(String[] args) { new Variable().a(1,3,5); } public void a( int... i){ System.out.println(i[0]); } }
形參,是方法聲明時,方法小括號內的參數;實參,是調用方法時,實際傳入的參數的值。
那麼,Java的實參值是如何傳入方法的呢?這是由Java方法的參數傳遞機制來控制的,Java裏方法的參數傳遞方式只有一種:值傳遞。所謂值傳遞,就是將實際參數值的副本(複製品)傳入方法內,而參數自己不會受到任何影響。
Java裏的參數傳遞相似於《西遊記》裏的孫悟空,孫悟空複製了一個假孫悟空,這個假孫悟空具備和孫悟空相同的能力,可除妖或被砍頭。但無論這個假孫悟空遇到什麼事,真孫悟空不會受到任何影響。與此相似,傳入方法的是實際參數值的複製品,無論方法中對這個複製品如何操做,實際參數值自己不會受到任何影響。
可是,當一個對象實例做爲一個參數被傳遞到方法中時,參數的值就是該對象的引用的一個副本。指向同一個對象,對象的內容能夠在被調用的方法中改變,但對象的引用(不是引用的副本)是永遠不會改變的。也就是說,在方法的執行過程當中,形參和實參的內容相同,指向同一塊內存地址,操做的其實都是源數據,因此方法的執行將會影響到實際對象。
類包含有構造器,Java語言經過new關鍵字來調用構造器,從而返回該類的實例。當建立對象實例時,構造器會被調用以根據類模板建立對象實例。
構造方法是指在一個類裏面,方法的名字與類的名字一致,且沒有返回值,包括void也沒有。簡單來講須要知足兩個條件:第一,方法名字和類名一致 ;第二,方法沒有任何返回值。構造器是一個特殊的方法。
定義構造器的語法格式以下:
[修飾符] 構造器名(形參列表) { //由零條到多條可執行性語句組成的構造器執行體 }
構造器的聲明看上去與方法聲明相似,可是構造器有本身的特色。
構造器既不能定義返回值類型,也不能使用void定義構造器沒有返回值。實際上,類的構造器是有返回值的,當咱們用new關鍵字來調用構造器時,構造器返回該類的實例,能夠把這個類的實例當成構造器的返回值,所以構造器的返回值類型老是當前類,無須定義返回值類型。但必須注意:不能在構造器裏顯式使用return來返回當前類的對象,由於構造器的返回值是隱式的。
若是沒有顯式地添加一個構造方法,Java會給每一個類默認自帶一個無參數的構造方法,若是咱們本身添加類的構造方法(不管是否無參),Java就不會再添加無參數的構造方法。這時候,就不能直接new一個對象而不傳遞參數了。因此咱們一直都在使用構造方法,這也是爲何建立對象的時候類名後面要有一個括號的緣由。
構造方法的重載和普通方法同樣。
構造方法不能被普通方法調用,只能經過new語句在建立對象的時候,間接調用。
只有在構造方法裏才能調用重載的構造方法,語法爲this+(實參列表)
,必須是方法的第一行,後面能夠繼續有代碼。
構造方法不能本身調用本身,這是一個死循環。
在調用重載的構造方法時,不可使用成員變量,由於在語意上講,這個對象尚未被初始化完成,處於中間狀態。
this關鍵字老是指向調用該方法的對象。this能夠用來修飾屬性、方法、構造器。
static修飾的方法中不能使用this引用。若是在static修飾的方法中使用this關鍵字,則這個關鍵字就沒法指向合適的對象。因此,static修飾的方法中不能使用this引用。
一般狀況下,this能夠省略,但若是方法的形參和類的屬性同名時,不能省略,表示此變量是屬性,而非形參。咱們在類的構造器中,能夠顯式的使用「this(形參列表)」方式,調用本類中指定的其餘構造器。但構造器中不能經過「this(形參列表)」方式調用本身。規定「this(形參列表)」必須聲明在當前構造器的首行。
/***用法有三種:*1.在本類的成員方法中,訪問本類的成員變量。 *2.在本類的成員方法中,訪問本類的另外一個成員方法。 *3.在本類的構造方法中,訪問本類的另外一個構造方法。 */ public class Zi extends Fu{ int num = 20; public Zi(){ this(134); //本類的無參構造,調用本類的有參構造 } public Zi(int n ){ } public Zi(int n, int m ){ } public void showNum(){ int num = 10; System.out.println(num); //局部變量 System.out.println(this.num); //本類中的成員變量 System.out.println(super.num); //父類中的成員變量 } }
public class Fu { int num =30; }
代碼塊的做用是用來初始化類或對象的。代碼塊只能使用static修飾,分爲非靜態代碼塊和靜態代碼塊。
public Hello { { //代碼塊 } }
代碼塊是隨着類加載或建立對象的時候執行的。非靜態代碼塊每建立一次對象執行一次,靜態代碼塊只能執行一次。
先加載靜態代碼塊,再加載非靜態代碼塊。同等的代碼塊按前後順序執行。