Q:子類對象的內(nèi)存中,是否包含父類中定義的private成員變量?
A:依然包含 private只是降低了訪問權限,不影響內(nèi)存布局和內(nèi)存分布,外界無法訪問,但是子類對象內(nèi)存中依然包含。子類內(nèi)存中包含父類所有的成員變量,無論是否是私有的
final
- 被final修飾的類不能被繼承
- 被final修飾的方法不能被重寫
- 被final修飾的變量,只能進行一次賦值
- 其他跟在Swift/Flutter中相似
常量
Java中常量一般寫成 名稱一般大寫 static final修飾的稱之為常量(約定俗成的叫法,final修飾也可以叫做常量)
private static final int MY_AGE = 1;
- 如果將基本類型或字符串定義為常量,并且在編譯時就能確定值,編譯器會使用常量值替換各處的常量名(類似于C語言的宏替換)
嵌套類
- 嵌套類:定義在另一個類中的類
public class OuterClass {
// 靜態(tài)嵌套類
static class StaticNestedClass {
}
// 非靜態(tài)嵌套類(內(nèi)部類)
class InnerClass {
}
}
- 在嵌套類外層的類,稱為:外部類(Outer Class)
- 最外層的外部類,稱為:頂級類(Top-level Class)
內(nèi)部類
內(nèi)部類:沒有被static修飾的嵌套類,非靜態(tài)嵌套類
- 跟實例變量,實例方法一樣,內(nèi)部類跟外部類實例相關聯(lián),
- 必須先創(chuàng)建外部類實例,然后通過外部類實例來創(chuàng)建內(nèi)部類實例
- 內(nèi)部類不能定義除了編譯時常量以外的任何
static成員 - 內(nèi)部類可以直接訪問外部類的所有成員(即使被聲明為private)
- 外部類可以直接訪問內(nèi)部類實例的成員變量、方法(即使被聲明為private)
- 內(nèi)部類實例內(nèi)存中有指向外部類實例的指針
OuterClass outer = new OuterClass();
// 通過外部類實例創(chuàng)建內(nèi)部類實例
InnerClass inner = outer.new InnerClass();
靜態(tài)嵌套類(Static Nested Class)
- 靜態(tài)嵌套類: 被
static修飾的嵌套類 - 靜態(tài)嵌套類在行為上就是一個頂層類,只是定義的代碼寫在了另一個類中
- 對比一般的頂級類,多了一些權限
- 可以直接訪問外部類中除了實例變量、實例方法之外的其他成員(即使被聲明為private)
public class OuterClass {
private static int count = 1;
// 靜態(tài)嵌套類
static class StaticNestedClass {
public void run() {
// 可以訪問頂層類的成員 即使是private
OuterClass.count = 1;
// 不需要類名也可以直接訪問外部類的成員
System.out.println(count);
}
}
}
什么情況使用嵌套類?
-
如果類A只在類C中使用,可以考慮把A嵌套在C中
- 封裝性更好
- 程序包更加簡化
- 增強可讀性,維護性
-
如果類A需要經(jīng)常訪問類C的非公開成員,可以考慮將A嵌套在C中
- 也可以考慮將A隱藏起來,不對外暴露
如果需要經(jīng)常訪問非公共的實例成員,設計成內(nèi)部類(非靜態(tài)嵌套類),否則設計成靜態(tài)嵌套類 (能靜態(tài)盡量去靜態(tài))
局部類
局部類:定義在代碼塊中的類(可以定義在方法中,for循環(huán)中,if語句中等代碼塊中)
局部類不能定義除了編譯時常量以外的任何static成員
-
局部類只能訪問
final或者 有效final的局部變量- Java 8開始,如果局部變量沒有第二次賦值,就認為是有效final
局部類可以直接訪問外部類的所有成員(即使被聲明為private)
局部類只有被定義在實例相關的代碼塊中,才能直接訪問外部類中的實例成員
public class LocalClass {
// 實例變量
public int age = 10;
// 靜態(tài)初始化塊 在類第一次初始化時調(diào)用
static {
class A {
public void test() {
// 跟實例相關的代碼塊中的局部類才能訪問實例成員
// 會報錯
// System.out.println(age);
}
}
A a = new A();
a.test();
}
// 初始化塊 在類的構造函數(shù)中調(diào)用
{
class A {
public void test() {
// 跟實例相關的代碼塊中的局部類才能訪問實例成員
System.out.println(age);
}
}
A a = new A();
a.test();
}
public void run(){
// count只賦值一次 被認為是有效fianl
int count = 0;
// 再次賦值的話就不被認為是有效final 局部類使用時會報錯
// count = 10;
// 局部類
class A {
// 報錯 不能定義除編譯時常量以外的static成員
// public static int age = 0;
// 正確
public static final int age = 10;
public void test() {
// 可以訪問final或者有效final的局部變量
System.out.println(count);
}
}
}
}
抽象類和抽象方法
-
抽象方法 :被
abstract修飾的方法- 只有方法聲明,沒有方法實現(xiàn)
- 不能是
private權限(因為定義抽象方法的目的就是讓子類去實現(xiàn)) - 只能是實例方法,不能是類方法
- 只能定義在抽象類、接口中
- 抽象類:被
abstract修飾的類- 可以定義抽象方法
- 不能實例化,但可以自定義構造函數(shù)
- 子類必須實現(xiàn)抽象父類中的所有抽象方法(除非子類也是一個抽象類)
- 可以像非抽象類一樣定義成員變量,常量,嵌套類,初始化塊,非抽象方法等
- 抽象類也可以完全不定義抽象方法
- 也就是說,抽象類比非抽象類多了一些抽象方法,但是不能實例化了
跟flutter中的抽象類似