1、Java基本語法
上一篇我們講到了Java的第一個程序HelloWorld
。並且用命令行的方式讓程序在控制檯輸出了Hello World字樣。這一篇,我們來大致說一下這段代碼是如何運行起來的。
首先,所有的Java程序,都必須要有一個稱之爲“主方法”的函數入口,這個入口便是public static void main(String []args)
方法(我們將它簡稱爲main
方法)。也就是說,要讓一個Java程序運行起來,就必須通過main
方法纔可以執行一系列的操作與運算,最終達到目的需求。
一段代碼的組成需要類名、變量名、和方法名,可以統稱爲Java的標識符。
1.1 標識符的命名規則
-
所有的標識符都應該以字母(A-Z、a-z)、數字、美元符($)、或者下劃線(_)組成
-
首字符只能以字母、$、下劃線(_)開頭
-
Java所定義的“關鍵字”不能作爲標識符使用
-
標識符大小寫敏感,如age和Age是由區別的
//正確的標識符命名:
bboyHan、_bboyHan、_bboy_$_23_han
//錯誤的命名:
23bboy、+23han、bboy&
1.2 Java關鍵字
1.1中提到了標識符的命名不能以“關鍵字”進行命名,我們來看一下Java的關鍵字有哪些:
類別 | 關鍵字 | 說明 |
---|---|---|
訪問控制 | private | 私有的 |
protected | 受保護的 | |
public | 公共的 | |
類、方法和變量修飾符 | abstract | 聲明抽象 |
class | 類 | |
extends | 擴充,繼承 | |
final | 最終值,不可改變的 | |
implements | 實現(接口) | |
interface | 接口 | |
native | 本地,原生方法(非 Java 實現) | |
new | 新,創建 | |
static | 靜態 | |
strictfp | 嚴格,精準 | |
synchronized | 線程,同步 | |
transient | 短暫 | |
volatile | 易失 | |
程序控制語句 | break | 跳出循環 |
case | 定義一個值以供 switch 選擇 | |
continue | 繼續 | |
default | 默認 | |
do | 運行 | |
else | 否則 | |
for | 循環 | |
if | 如果 | |
instanceof | 實例 | |
return | 返回 | |
switch | 根據值選擇執行 | |
while | 循環 | |
錯誤處理 | assert | 斷言表達式是否爲真 |
catch | 捕捉異常 | |
finally | 有沒有異常都執行 | |
throw | 拋出一個異常對象 | |
throws | 聲明一個異常可能被拋出 | |
try | 捕獲異常 | |
包相關 | import | 引入 |
package | 包 | |
基本類型 | boolean | 布爾型 |
byte | 字節型 | |
char | 字符型 | |
double | 雙精度浮點 | |
float | 單精度浮點 | |
int | 整型 | |
long | 長整型 | |
short | 短整型 | |
變量引用 | super | 父類,超類 |
this | 本類 | |
void | 無返回值 | |
保留關鍵字 | goto | 是關鍵字,但不能使用 |
const | 是關鍵字,但不能使用 | |
null | 空 |
2、面向對象
既然說Java是一個面向對象的設計語言,那什麼是面向對象?
提到“面向對象”,就必然會提到“面向過程”。面向過程(Procedure Oriented),就是計算機執行一段“過程化”的敘事思維,比如說“打開電腦”這個動作,“電腦”作爲對象的參數傳入方法中,然後在方法內定義打開電腦的具體步驟。而面向對象(Object Oriented),是把構成問題事務分解成各個對象,建立對象的目的不是爲了完成一個步驟,而是爲了描敘某個事物在整個解決問題的步驟中的行爲。還以“打開電腦”這個例子來說,面向對象的編程,就是將電腦抽象出來,定義電腦的相關屬性(如大小、CPU、各種硬件組成)和操作行爲(如開機、關機、重啓),進而解決這一問題。
2.1 對象和類
Java之父Gosling設計的Object類,是任何類的默認父類,即是萬事萬物的抽象,高度概括了事物的自然行爲和社會行爲。類相當於是某個具體事物的進一步抽象。如Iphone、小米、華爲P30可以統稱爲“手機類”,王者農藥、吃雞、消消樂都是“遊戲類”。對象,就是這其中一個個具體的事物,如Iphone是一個對象,小米是一個對象。
類的定義由訪問級別、類型、類名、是否抽象、是否靜態、泛型標識、繼承等組成。類型分爲class、enum(枚舉)、interface(接口),類的訪問級別有public和無訪問控制符。
2.2 修飾符、變量與方法
面向對象編程,就是一個對象先抽象出模型,在定義共性特徵和行爲,進而解決實際問題。
- 變量
Java的變量,我們可以把它理解爲一個對象的屬性特徵,比如小米手機,它有長寬高、重量、使用壽命、內存等等。
- 方法
是指對象的操作行爲,比如小米手機可以打電話、開機、關機、充電等等。
- 修飾符
Java通過對變量和方法進行不同的修飾,可以做到將對象的行爲和屬性進行對外或對內的訪問限制,即公有化、私有化。如我的小米手機需要指紋才能解鎖、我的電話通訊錄只有我才能看,手機外觀所有人都可以看到…Java可以使用修飾符來修飾類中方法和屬性。主要有兩類修飾符:
訪問修飾符
Java中,可以使用訪問控制符來保護對類、變量、方法和構造方法的訪問。Java 支持 4 種不同的訪問權限。
訪問權限 | public | protected | default | private |
---|---|---|---|---|
同一個類 | yes | yes | yes | yes |
同一個包 | yes | yes | yes | no |
子類 | yes | yes | no | no |
其它類 | yes | no | no | no |
非訪問修飾符
爲了實現一些其他的功能,Java 也提供了5種非訪問修飾符。
修飾符 | 說明 |
---|---|
static | 靜態修飾符,修飾類方法和類變量。 |
final | 最終修飾符,修飾類、方法和變量,修飾的類不能夠被繼承,修飾的方法不能被重新定義,修飾的變量表示爲不可修改的常量。 |
abstract | 抽象修飾符,用來創建抽象類和抽象方法。 |
synchronized | 修飾符,用於線程編程。 |
transient | 修飾符,用於跳過序列化對象中特定的敏感變量 |
volatile | 修飾符,用於線程編程。 |
注意點:所謂friendly/default,即指的是在類前不加任何修飾符的情況,並不是真的有這樣一個“修飾符”。
- 修飾符修飾類、方法和變量的詳細列表
類別 | 修飾符 | 說明 |
---|---|---|
類修飾符 | public | 將一個類聲明爲公共類,他可以被任何對象訪問,一個程序的主類必須是公共類。 |
abstract | 將一個類聲明爲抽象類,沒有實現的方法,需要子類提供方法實現。 | |
final | 將一個類生命爲最終(即非繼承類),表示他不能被其他類繼承。 | |
friendly | 默認的修飾符,只有在相同包中的對象才能使用這樣的類。 | |
成員變量修飾符 | public | 指定該變量爲公共的,他可以被任何對象的方法訪問。 |
private | 私有訪問控制符,指定該變量只允許自己的類的方法訪問,其他任何類(包括子類)中的方法均不能訪問。 | |
protected | 保護訪問控制符,指定該變量可以別被自己的類和子類訪問。在子類中可以覆蓋此變量。 | |
friendly | 在同一個包中的類可以訪問,其他包中的類不能訪問。 | |
final | 最終修飾符,指定此變量的值不能變。 | |
static | 靜態修飾符,指定變量被所有對象共享,即所有實例都可以使用該變量。變量屬於這個類。 | |
transient | 過度修飾符,讓某些被修飾的成員屬性變量不被序列化。 | |
volatile | 易失修飾符,指定該變量可以同時被幾個線程控制和修改。 | |
方法修飾符 | public | 公共控制符 |
private | 私有控制符,指定此方法只能有自己類等方法訪問,其他的類不能訪問(包括子類) | |
protected | 保護訪問控制符,指定該方法可以被它的類和子類進行訪問。 | |
final | 指定該方法不能被重載。 | |
static | 指定不需要實例化就可以激活的一個方法。 | |
synchronize | 同步修飾符,在多個線程中,該修飾符用於在運行前,對他所屬的方法加鎖,以防止其他線程的訪問,運行結束後解鎖。 | |
native | 本地修飾符。指定此方法的方法體是用其他語言在程序外部編寫的。 | |
void | 無返回值 |
- 定義一個類
//定義一個小米手機類
public class XiaoMi{
//定義屬性
public int weight; //重量,所有人可看,用public修飾
private List phoneList; //聯繫人列表,僅自己可見,用private修飾
//定義方法
public void callPhone(String phoneNumber){
//...打電話
}
private void unlockPhone(String password){
//...指紋解鎖
}
}
2.3 封裝、繼承、多態
有了面向對象的編程思想之後,就具備了一定的建模能力。將現實中的一些具體業務進行“抽象”,通過一定的項目實踐,積累經驗。便可掌握Java編程過程中的一大關鍵要素。抽象,是面向對象思想最基本的能力之一,正確而嚴謹的業務抽象和建模分析能力,便是後續的封裝、繼承、多態的基礎。
Java編程中,必須瞭解面向對象的三大特性,即封裝、繼承、多態
- 封裝
封裝思想的核心,就是“隱藏細節”、“數據安全”:將對象不需要讓外界訪問的成員變量和方法私有化,只提供符合開發者意願的公有方法來訪問這些數據和邏輯,保證了數據的安全和程序的穩定。
實現思路:
使用 private 修飾符把成員變量設置爲私有,防止外部程序直接隨意調用或修改成員變量,然後對外提供public 的 set 和 get 方法按照開發者的意願設置和獲取成員變量的值。
a、修改屬性的可見性——設爲private;
b、創建getter/setter方法,用於屬性的讀寫;
c、在getter/setter方法中加入屬性控制語句,對屬性值的合法性進行判斷。
補充: 既然通過getter/setter方法來進行讀取和修改,那與直接對屬性進行操作有什麼區別?
答: 在實際場景中,我們通常會在setter方法對屬性賦值過程中,進行其他的一些操作(如鑑權控制、日誌記錄、參數驗證等),而直接對屬性進行修改是無法做到的。
class People{
private int age;
public void setAge(int age){
//...其它邏輯
this.age = age;
}
public int getAge(){
//...其它邏輯
return age;
}
public void doWork(){
//做一些事
}
}
- 繼承
繼承是類與類的一種關係,例如:動物和狗的關係,動物是父類(或基類),狗是子類(或派生類)。要注意的是,在Java中的繼承是單繼承,也就是說一個兒子只能有一個爸爸,一個子類只允許有一個父類。
使用繼承的優勢在於,子類擁有父類的所有屬性和方法(private除外),並且子類可以複用父類的代碼。
使用繼承,創建出具有邏輯等級結構的類體系,形成一個繼承Tree,對後續的業務使用和代碼複用可以帶來非常大的便利。
- 多態
多態,是指運行時的實際對象類型,在同一個方法下產生不同的運行結果,使得同一個行爲具有不同的表現形式。
class Student extends People{
public void doWork(){
//做作業
}
}
class Worker extends People{
public void doWork(){
//上班
}
}
補充:
多態的體現在於子類繼承父類後,不滿足父類方法的基本要求,而進行“覆寫”(override)完善。在這裏,初學者朋友經常會將override
與overload
相互混淆。
-
override: 指的是重寫父類方法,返回值類型、方法名、參數類型及個數,都與從父類繼承的方法相同。
-
overload: 重載,指的是方法名相同,但參數類型或參數個數不同。
Java的多態,指在編譯層面無法確定最終調用的方法體,以**“覆寫”(override)爲基礎來實現面向對象的特性,在運行期由JVM進行動態綁定,調用合適的覆寫方法體來執行。而重載(overload)**則是編譯器確定的方法調用,屬於靜態綁定。本質上二者毫不相干也毫無關聯!!