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号