訪問控制
- 控制訪問符
- 修飾符
- 例題
訪問控制符的類型
- public
- friendly
- protected
- private
控制的對象
- 類(protected和private除外)
- 方法
- 成員變量
控制的範圍
類內部 | 相同包的子類 | 相同包的其他類 | 不同包的子類 | 不同包的其他類 | |
---|---|---|---|---|---|
public | ✔ | ✔ | ✔ | ✔ | ✔ |
protected | ✔ | ✔ | ✔ | ✔ | ✖ |
friendly | ✔ | ✔ | ✔ | ✖ | ✖ |
private | ✔ | ✖ | ✖ | ✖ | ✖ |
修飾符
static(靜態的)
可修飾的對象
- 類
- 屬性
- 方法
- 代碼塊
修飾後的作用
- 類:只能修飾內部類,不能修飾外部類。該內部類將與外部類一同被加載到方法區,不依賴對象存在
- 屬性:
- 該屬性將與類的信息一同被加載到方法區,不依賴對象存在(在對象被new出來之前,該屬性就已經存在於方法區)
- 該屬性爲所有對象共有,即所有對象共享一個屬性。
- 方法:參照上面
- 可以滿足重寫的條件,但是不能被重寫
- 代碼塊:參照上面
被修飾對象的使用
- 屬性:類名.屬性名
- 方法:類名.方法名()
static:
- 不能在靜態方法中使用this,因爲靜態方法加載時時不存在對象
- 不能在靜態方法中調用屬性和方法,原因同上
- 可以在普通方法中直接調用(不new對象)靜態的屬性和方法,因爲調用普通方法的前提是對象存在
final(最終的)
可修飾的對象
- 類
- 屬性
- 方法
修飾後的作用
- 類:該類不能被繼承,但是可以繼承其他類
- 常見的final類:String
- 屬性:變量成爲常量
- 必須在對象生成前初始化(聲明的同時賦值,普通代碼塊,構造器)
- 不能二次賦值
- 不能參與計算
- 方法:不允許重寫
常量:
- 引用類型的常量,可以修改內部的屬性,但是不能修改引用的對象
- 常量的字母全部大寫,多個單詞用"_"拼接
- 常量的訪問控制符一般是public
static+final
可修飾的對象
- 屬性(靜態常量)
- 方法(很少)
修飾後的作用
- 不依賴對象存在,且所有對象共用
- [類名.常量名]直接調用
- 不能被修改
- 必須在對象生成前初始化(聲明的同時初始化,靜態代碼塊)
被修飾對象的使用
- 屬性:訪問控制符 static final 類型 常量名
創建對象的過程
- 加載類(先)
- 類的信息
- static修飾的屬性、方法、代碼塊
- 順序:寫在前面的先加載,寫在後面的後加載,且都只會加載一次
- 創建對象(後)
- new(1)
- 執行普通代碼塊(2)
- 執行構造方法(3)
題目
問題1:以下代碼的輸出結果
package day20191103;
public class Demo01 {
static {
System.out.println("父類靜態代碼塊");
}
{
System.out.println("父類普通代碼塊");
}
Demo01(){
System.out.println("父類構造器");
}
}
class Demo extends Demo01{
static {
System.out.println("子類靜態代碼塊");
}
{
System.out.println("子類普通代碼塊");
}
Demo(){
System.out.println("子類構造器");
}
}
-------------------------------------------------------------------
package day20191103;
public class Demo02 {
public static void main(String[] args) {
new Demo();
}
}
上述題目的輸出結果爲:
父類靜態代碼塊
子類靜態代碼塊
父類普通代碼塊
父類構造器
子類普通代碼塊
子類構造器從結果中,我們可以得出創建子類對象時的過程:
- 加載父、子類的靜態代碼塊
- 創建父類對象(普通代碼塊—>構造方法)
- 創建子類對象(普通代碼塊—>構造方法)
結論與我們之前所說的“創建子類對象之前必須先創建父類對象“相符
問題2:爲什麼main方法是靜態的
main方法又叫程序入口,在剛進入程序的時候,沒有對象被創建(包括主方法所在的類),所以必須用static修飾主方法
問題3:類什麼時候被加載
- 創建自身對象
- 創建子類對象(父類也會被加載)
- 調用靜態方法(父類也會被加載)
- 調用靜態屬性(父類也會被加載)
- 反射(類名.class)