1、final關鍵字
學習了繼承後,我們知道,子類可以在父類的基礎上改寫父類內容,比如,方法重寫。那麼我們能不能隨意的繼承 API中提供的類,改寫其內容呢?顯然這是不合適的。爲了避免這種隨意改寫的情況,Java提供了 final 關鍵字, 用於修飾不可改變內容。
fifinal: 不可改變。可以用於修飾類、方法和變量。
類:被修飾的類,不能被繼承。
方法:被修飾的方法,不能被重寫。
變量:被修飾的變量,不能被重新賦值。
使用方式:final class 類名 { }
修飾方法:
修飾符 final 返回值類型 方法名(參數列表){
//方法體
}
重寫被 final 修飾的方法,編譯時就會報錯。
修飾變量
- 局部變量——基本類型
基本類型的局部變量,被fifinal修飾後,只能賦值一次,不能再更改。代碼如下:
public class FinalDemo1 {
public static void main(String[] args) {
// 聲明變量,使用final修飾
final int a;
// 第一次賦值
a = 10;
// 第二次賦值
a = 20;
// 報錯,不可重新賦值
// 聲明變量,直接賦值,使用final修飾
final int b = 10;
// 第二次賦值
b = 20;
// 報錯,不可重新賦值
}
}
思考,如下兩種寫法,哪種可以通過編譯? 寫法1: final int c = 0; for (int i = 0; i < 10; i++) { c = i; System.out.println(c); }
寫法2: for (int i = 0; i < 10; i++) { final int c = i; System.out.println(c); }
根據 final 的定義,寫法1報錯!寫法2,爲什麼通過編譯呢?因爲每次循環,都是一次新的變量c。這也是大家 需要注意的地方。
- 局部變量——引用類型
引用類型的局部變量,被final修飾後,只能指向一個對象,地址不能再更改。但是不影響對象內部的成員變量值的 修改,代碼如下:
public class FinalDemo2 {
public static void main(String[] args) {
// 創建 User 對象
final User u = new User();
// 創建 另一個 User對象
u = new User();
// 報錯,指向了新的對象,地址值改變。
// 調用setName方法
u.setName("張三");
// 可以修改
}
}
- 成員變量
成員變量涉及到初始化的問題,初始化方式有兩種,只能二選一:
顯示初始化;public class User { final String USERNAME = "張三"; private int age; }
構造方法初始化。 public class User { final String USERNAME ; private int age; public User(String username, int age) { this.USERNAME = username; this.age = age; } }
被final修飾的常量名稱,一般都有書寫規範,所有字母都大寫。
權限修飾符
在Java中提供了四種訪問權限,使用不同的訪問權限修飾符修飾時,被修飾的內容會有不同的訪問權限,
public:公共的。 protected:受保護的 default:默認的 private:私有的
不同權限的訪問能力
可見,public具有最大權限。private則是最小權限。 編寫代碼時,如果沒有特殊的考慮,建議這樣使用權限:
成員變量使用 private ,隱藏細節。 構造方法使用 public ,方便創建對象。 成員方法使用 public ,方便調用方法。
不加權限修飾符,其訪問能力與default修飾符相同
內部類
將一個類A定義在另一個類B裏面,裏面的那個類A就稱爲內部類,B則稱爲外部類
成員內部類
成員內部類 :定義在類中方法外的類。
定義格式:
class 外部類 {
class 內部類{
}
}
在描述事物時,若一個事物內部還包含其他事物,就可以使用內部類這種結構。比如,汽車類 Car 中包含發動機 類 Engine ,這時, Engine 就可以使用內部類來描述,定義在成員位置。
代碼舉例: class Car { //外部類 class Engine { //內部類 } }