JAVA基礎--內部類
JAVA基礎--內部類
Java類中不僅可以定義變量和方法還可以定義類,這樣定義在類內部的類就被稱為內部類。根據定義方式的不同,內部類分為靜態內部類、成員內部類、局部內部類、匿名內部類四種。
一、靜態內部類
定義在類內部的靜態類,就是靜態內部類。靜態內部類是定義在外部類的成員位置上,且有static修飾。
Java 集合類HashMap內部就有一個靜態內部類Node,Node是HashMap存放元素的類。
HashMap內部維護Node數組存放元素,但是Node對使用者是透明的。像這種和外部類關系密切的,且不依賴外部類實例的,都可以使用靜態內部類。
用法:
- 靜態內部類,可以訪問外部類的所有靜態成員(變量)和方法,即使是
private的也一樣。但不能直接訪問非靜態的成員; - 可以添加任意訪問修飾符,因為它的地位就是一個成員;
- 作用域和外部類的其他成員一樣,是整個類體;
- 靜態內部類和一般的類一樣,可以定義變量、方法、構造方法等;
- 如果內部類和外部類有成員重名時,遵循就近原則。如果想訪問外部類成員,則可以使用“外部類名.成員”;
- 其他類使用靜態內部類需要使用“外部類.靜態內部類”方式;
代碼示例:
public class Monster {
private String name;
private static final int TYPE = 1;
/**
* 靜態內部類
*/
public static class Sub{
private static final int TYPE = 2;
public void printInfo(){
System.out.println("怪物類型:" + TYPE);
System.out.println("外部怪物類型:" + Monster.TYPE);
// 無法訪問外部類的 非靜態成員
// System.out.println("怪物name:" + name);
}
}
public static void main(String[] args){
Monster.Sub sub = new Monster.Sub();
sub.printInfo();
}
}
結果:
怪物類型:2
外部怪物類型:1
二、成員內部類
定義在類內部成員位置上的非靜態類,就是成員內部類。
用法:
- 不能定義靜態方法和變量(final 修飾的除外)。這是因為成員內部類是非靜態的,類初始化的時候先初始化靜態成員,如果允許成員內部類定義靜態變量,那么成員內部類的靜態變量初始化順序是有歧義的;
- 可以直接訪問外部類的所有成員,包括
private。外部類訪問成員內部類的訪問方式:創建對象,再訪問; - 作用域與外部類的其他成員一樣,是整個類體;
- 如果內部類和外部類有成員重名時,遵循就近原則。如果想訪問外部類成員,則可以使用“外部類名.this.成員”;
- 外部其他類訪問成員內部類的三種方式:1、實例化外部類,通過外部類方法訪問;2、將內部類作為外部類的成員實例化然后訪問;3、在外部類里編寫一個方法返回內部類對象。
代碼示例:
public class Monster {
private String name;
private static final int TYPE = 1;
public Monster(String name){
this.name = name;
}
/**
* 成員內部類
* 投擲物
*/
public class Missile{
private String name;
public Missile(String name){
this.name = name;
}
public void printInfo(){
System.out.println("怪物類型:" + TYPE);
System.out.println("投擲物名稱:" + name);
System.out.println("怪物名稱:" + Monster.this.name);
}
}
public void shutWater(){
Missile water = new Missile("水");
water.printInfo();
}
public Missile getFire(){
return new Missile("火焰");
}
public static void main(String[] args){
// 成員內部類
Monster monster = new Monster("龍");
// 第一種 通過外部類方法訪問
// monster.shutWater();
// 第二種 將內部類作為成員實例化訪問
// Monster.Missile thunder = monster.new Missile("雷電");
// 第三種 外部類方法返回內部類
Monster.Missile fire = monster.getFire();
fire.printInfo();
}
結果:
怪物類型:1
投擲物名稱:火焰
怪物名稱:龍
}
三、局部內部類
定義在方法中的類就是局部內部類。
用法:
- 可以訪問外部類所有成員、方法,包括
private。外部類成員可以直接訪問; - 可以使用
final修飾; - 如果內部類和外部類有成員重名時,遵循就近原則。如果想訪問外部類成員,則可以使用“外部類名.this.成員”;
- 作用域為定義它的方法或代碼塊中;
- 外部類訪問局部內部類方式:創建對象,再訪問;
- 外部其他類不能直接訪問局部內部類;
代碼示例:
public class Monster {
private String name;
private static final int TYPE = 1;
public Monster(String name){
this.name = name;
}
public String getName(){
return this.name;
}
/**
* 繁衍
*/
public void multiply(){
class Egg{
private String name;
public Egg(String name){
this.name = name;
}
public void hatch(){
System.out.println("怪物類型:" + TYPE);
Monster monster = new Monster("小龍");
System.out.println("孵化:" +Monster.this.name + " 的 " + name + " 孵化出新的怪物 " + monster.getName());
}
}
Egg egg = new Egg("龍蛋");
egg.hatch();
}
public static void main(String[] args){
// 局部內部類
Monster monster = new Monster("龍");
monster.multiply();
}
}
結果:
怪物類型:1
孵化:龍 的 龍蛋 孵化出新的怪物 小龍
四、匿名內部類
匿名內部類必須要繼承一個類或實現一個接口,直接使用new來生成一個對象的引用。
用法:
- 匿名內部類是局部內部類的一種簡化形式,本質上是一個對象,是實現類該接口或繼承了該類的子類對象;
- 語法格式:
new 類名或接口名(){ 重寫方法 }; - 經常作為參數或返回值,使用方便;
- 使用匿名內部類可以實現:一個類中嵌套一個接口;
代碼示例:
public class Monster {
private String name;
private static final int TYPE = 1;
public Monster(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void multiply(){
System.out.println("怪物繁衍");
}
public static void main(String[] args){
// 匿名內部類
Monster dragon = new Monster("龍"){
@Override
public void multiply(){
System.out.println(this.getName() + "生小龍");
}
};
dragon.multiply();
Monster snake = new Monster("蛇"){
@Override
public void multiply(){
System.out.println(this.getName() + "生小蛇");
}
};
snake.multiply();
}
}

浙公網安備 33010602011771號