寫到這裏終於寫到了入門篇的最後一個知識點了。類和對象是Java中常常被提到的兩個詞彙,實際上能夠將類看做對象的載體,它定義了對象所具備的功能。Java是面向對象的語言,所以掌握類與對象是學習Java語言的基礎。數組
類和對象的概念就不在此描述了,這篇隨筆仍是主要從代碼方面入手,在學習本篇前建議先了解一下類和對象的概念、實例的概念以及面向對象程序的特色,也即封裝、繼承、多態。學習
類是封裝對象的屬性和行爲的載體,在Java語言中對象的屬性以成員變量的形式存在,而對象的方法以成員方法的形式存在。this
構造方法是一個與類同名的方法,對象的建立就是經過構造方法完成的,構造方法分爲有參構造方法和無參構造方法,區別就在於有沒有參數。說這麼多概念是否是感受有點麻木,直接看下面的例子吧。spa
1 public class Example { 2 3 public Example() { // 定義無參構造方法 4 System.out.println("無參構造方法"); 5 } 6 7 public Example(String name) { // 定義有參構造方法 8 System.out.println("有參構造方法"); 9 } 10 11 }
在定義構造方法時,構造方法沒有返回值,且構造方法不須要void關鍵字進行修飾。「public」是構造方法的修飾符,「Example」是構造方法的名稱。設計
在構造方法中能夠爲成員變量賦值,這樣當實例化一個本類的對象時,相應的成員變量也將被初始化。code
主方法其實咱們已經見過不少次了,Java編譯器經過主方法來執行程序,是類的入口點,語法格式以下:對象
public static void main(String[] args) { // ... }
「static」是指主方法是靜態的,若在其中調用其它方法,則該方法也必須是靜態的;」void」是指主方法沒有返回值;「String[] args」是指主方法的形參爲數組,用args[0]~args[n]分別表示程序的第一到第n個參數,可使用args.length獲取參數的個數。blog
對象的屬性稱爲成員變量,也可稱爲屬性。下面以學生類(可比做學生證)舉個例子:繼承
1 public class Student { 2 private int id; // 定義一個int型成員變量,學號 3 private String name; // 定義一個String型成員變量, 姓名 4 5 public Student() { // 定義無參構造方法 6 7 } 8 public Student(int id, String name) { // 定義有參構造方法 9 this.id = id; 10 this.name = name; 11 } 12 13 public void setName(String name) { // 定義一個setName()方法,用於導入學生姓名 14 this.name = name; // 將參數值賦給成員變量 15 } 16 public String getName() { // 定義一個getName()方法,用於獲取學生姓名 17 return this.name; 18 } 19 20 public Student getStudent() { // 返回Student類引用 21 return this; 22 } 23 }
這就是個比較全的例子了,在Java語言中使用class關鍵字來定義類,Student是類的名稱;在Student類中定義了三個成員變量,分別爲學號和姓名,可設置初始值也可不設置初始值,若不設置初始值則會有默認值;private關鍵字用於定義一個私有成員,後面會介紹public、protected和private。接下來的兩個構造方法上面已經提到過了,this關鍵字用於引用對象的成員變量和方法,在後面會有所介紹。通常在這樣的類中每個變量都會有set和get方法,set方法是帶參數的方法沒有返回值,get方法是有返回值的方法,用於獲取。最後還有一個getStudent()方法,它的類型是Student類的,用於返回Student類的引用,用this關鍵字實現。接口
成員方法對應類的行爲,就是上述實例中的getName()和setName()方法,分別爲獲取學生姓名和設置學生姓名的方法,語法格式以下:
權限修飾符 返回值類型 方法名(參數類型 參數名){ // ... return 返回值; }
若無返回值,返回值類型用void關鍵字表示,如上述setName()方法。如有返回值,返回值類型要與方法返回值類型一致。
若是在成員方法中定義一個變量,那麼這個變量別稱爲局部變量。例如在上述Student類中的getName()方法中定義一個局部變量id以下:
public String getName() { int id = 0; // 定義一個局部變量 return id + this.name; }
局部變量是在方法執行時建立,在方法執行結束時被銷燬,使用時必須賦值或初始化。因此局部變量的有效範圍從該變量的聲明開始到該變量的結束爲止。
若一個方法中含有與成員變量同名的局部變量,則方法中對這個變量的訪問以局部變量進行訪問。例如id,在上述方法中id=0,而不是Student類中的成員變量id的值。
由static修飾的變量、常量和方法被稱做靜態變量、常量和方法。靜態成員是屬於類全部的,區別於個別對象,能夠在本類或其餘類中使用類名和「.」運算符調用,這個在以前的篇幅中的例子也出現過,語法格式爲: 類名.靜態類成員 。
1 public class StaticTest { 2 final static double PI = 3.1415926; // 在類中定義靜態常量 3 static int id; // 在類中定義靜態變量 4 5 public static void demo01() { 6 System.out.println("test"); 7 } 8 public static void main(String[] args) { 9 System.out.println(StaticTest.PI); // 調用靜態常量 10 System.out.println(StaticTest.id); // 調用靜態變量 11 StaticTest.demo01(); // 調用靜態方法 12 } 13 14 }
Java中的權限修飾符主要包括private、public和protected,這些修飾符控制着對類和類的成員變量以及成員方法的訪問。區別見下表:
訪問位置 | 類修飾符 | ||
private | protected | public | |
本類 | 可見 | 可見 | 可見 |
同包其餘類或子類 | 不可見 | 可見 | 可見 |
其餘包的類或子類 | 不可見 | 不可見 | 可見 |
若一個類的訪問權限爲不可見,這個類將隱藏其內的全部數據,以避免用戶直接訪問它。當聲明類時不使用public、protected或private修飾符設置類的權限,則這個類預設爲包存取範圍,即只有同一個包中的類能夠調用這個類的成員變量或成員方法。
要特別注意如下狀況,在項目中com.adamjwh包下建立AnyClass類,該類使用默認權限時:
package com.adamjwh; class AnyClass { public void doString() { // ... } }
此時,即便AnyClass類中的doString()方法又被設置成public訪問權限,其訪問權限也與AnyClass類的訪問權限相同。由於Java規定,類的權限設定會約束類的成員上的權限設定,因此上述代碼等同於下面的代碼:
package com.adamjwh; class AnyClass { void doString() { // ... } }
在Java中,this關鍵字被隱式地用於引用對象的成員變量和方法,如前面「成員變量」中的例子:
public void setName(String name) { // 定義一個setName()方法,用於導入學生姓名 this.name = name; // 將參數值賦給成員變量 }
setName()方法中,this.name指定的就是Student類中name變量,而「this.name=name」語句中第二個name則指定的是形參name。實質上,setName()方法實現的功能就是將形參name的值賦予成員變量name。
this除了能夠調用成員變量或成員方法以外,還能夠做爲方法的返回值。如前面「成員變量」中的例子:
public Student getStudent() { // 返回Student類引用 return this; }
在getStudent()方法中,方法的返回值爲Student類,因此方法體中使用return this這種形式將Student類的對象進行返回。
Java是面向對象的程序設計語言,對象是由類抽象出來的,全部的問題都是經過對象來處理,對象能夠操做類的基本屬性和方法解決相應的問題。
在Java中可使用new操做符調用構造方法建立對象,語法格式以下:
Test test = new Test(); Test test = new Test("a");
test對象被建立出來時,test對象就是一個對象的引用,這個引用在內存中爲對象分配了存儲空間,能夠在構造方法中初始化成員變量,當建立對象時,自動調用構造方法。
在Java中對象和實例事實上能夠通用,下面看一個建立對象的實例。
public class CreateObject { public CreateObject() { // 構造方法 System.out.println("test"); } public static void main(String[] args) { new CreateObject(); // 建立對象
在上述實例的主方法中使用new操做符建立對象,在建立對象的同時,自動調用構造方法中的代碼。
當用戶使用new操做符建立一個對象後,可使用「對象.類成員」來獲取對象的屬性和行爲。話很少說,直接上代碼。
1 public class ObjectTest { 2 3 int i = 2018; // 成員變量 4 public void call() { // 成員方法 5 for(i=0; i<3; i++) { 6 System.out.print(i + " "); 7 if(i == 2 ) { 8 System.out.println(); // 換行 9 } 10 } 11 } 12 13 public ObjectTest() { // 構造方法 14 } 15 16 public static void main(String[] args) { 17 ObjectTest o1 = new ObjectTest(); // 建立一個對象 18 ObjectTest o2 = new ObjectTest(); // 建立另外一個對象 19 o2.i = 60; // 給第二個類成員變量賦值 20 21 System.out.println("第一個實例對象調用變量i的結果爲:"+ o1.i); 22 o1.call(); 23 System.out.println("第二個實例對象調用變量i的結果爲:"+ o2.i); 24 o2.call(); 25 } 26 27 }
運行結果以下:
這裏咱們能夠看到,雖然使用兩個對象調用同一個成員變量,結果卻不相同,由於在打印這個成員變量的值以前將該值從新賦值爲60,但在賦值時使用的是第二個對象o2調用的成員變量,因此在第一個對象o1調用成員變量打印該值時仍然是成員變量的初始值。因此兩個對象的產生是相互獨立的。
若是但願成員變量不被其中任何一個對象改變,可使用static關鍵字,也即改第三行代碼爲 static int i = 2018; ,運行結果以下:
這裏因爲第19行代碼「o2.i=60;」改變了靜態成員變量的值,因此使對象o1調用成員變量的值也變爲了60;當「o1.i」執行完後,再次調用call()方法,使i的值又從新賦值爲0,循環打印,最後i爲3,退出循環,因此對象o2調用成員變量的值變成了3。
對象引用的語法格式爲: 類名 引用對象名稱 ,例如一個Student類的引用能夠爲: Student student; ,引用與對象相關聯的語法爲: Student student = new Student(); .
對象的比較有「==」運算符和equals()方法兩種,區別在上一篇中已經介紹過了。equals()方法是String類中的方法,用於比較兩個對象引用所指的內容是否相等;而「==」運算符比較的是兩個對象引用的地址是否相等。
對象的銷燬利用的是Java中的垃圾回收機制,用戶沒必要擔憂廢棄的對象佔用內存,垃圾回收器將回收無用的佔用內存的資源。會被Java虛擬機視爲垃圾的對象主要包括如下兩種狀況:
(1) 對象引用超過其做用範圍;
(2) 將對象賦值爲null;
雖然垃圾回收機制已經很完善,但垃圾回收器只能回收那些由new操做符建立的對象。因此Java中提供了一個finalize()方法,若是用戶在類中定義了finalize()方法,在垃圾回收時首先調用該方法,而且在下一次垃圾回收動做發生時,才能真正的回收對象佔有的內存。因爲垃圾回收不受人爲控制,Java還提供了System.gc()方法強制啓動垃圾回收器,做用是告知垃圾回收器來清理。
到此就是Java入門篇的所有內容了,要熟練使用Java語言還有許多知識等着咱們去挖掘,掌握入門篇的知識應付學校的考試之類的是沒有問題的,若是還想作一些遊戲或項目,還須要進一步學習Java語言的知識,下一篇開始就是Java的進階篇了,主要內容包括接口、繼承、多態、異常處理、輸入輸出、Java集合類以及Swing程序設計(圖形界面)等等。