7.19
在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。
一、内部类基础:
1、成员内部类:
成员内部类看起来像是外部类的一个成员,所以内部类可以拥有private、public等访问权限修饰;当然,也可以用static来修饰。成员内部类分为:
静态成员内部类:使用static修饰类;
非静态成员内部类:未用static修饰类,在没有说明是静态成员内部类时,默认成员内部类指的就是非静态成员内部类;
注:只有成员内部类才能加static变成静态内部类。
1.1)静态内部类:
使用static修饰的内部类我们称之为静态内部类,我们要知道只要是static修饰的类那它一定是内部类,不可能是外部类。静态内部类与非静态内部类之间存在一个最大的区别,非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类的对象,但是静态内部类却没有。没有这个引用就意味着:
它的创建是不需要依赖于外围类的对象
它不能使用任何外围类的非static成员变量和方法(因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象)
静态内部类内允许有static属性、方法;
class OutClass {
static class InnerClass {
static String test = "test";
int a = 1;
static void fun1() {}
void fun2() {}
}
}
1.2)非静态成员内部类:
public class Circle {
private double radius = 0.0;
public static int count = 1;
public Circle(double radius) {
this.radius = radius;
}
public class Draw {//内部类
public void drawSahpe() {
System.out.println(radius);//外部类的private成员
System.out.prinlt(count);//外部类的静态成员
}
}
}
1)成员内部类访问外部类的信息:
类Draw像是类Circle的一个成员,Circle称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
注:当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
2)创建内部类对象:
成员内部类是依附外部类而存在的,所以要创建成员内部类的对象,前提是必须存在一个外部类的对象。通常有如下两种方法:
public class OutClass {
private InnerClass getInner() {
return new InnerClass();
}
public class InnerClass{}
public static void main(String... str) {
OutClass out = new OutClass();
InnerClass inner1 = out.getInner();
InnerClass inner2 = out.new InnerCLass();
}
}
3)外部类访问成员内部类信息:
同样,外部类也可以访问内部类的所有成员变量和方法(包括private),但外部类想访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
public class OutClass {
public static int count = 12;
private double radius;
public OutClass(double radius) {
this.radius = radius;
}
public class InnerClass {//内部类
public String name = "test";
public void test() {
System.out.println(count);//访问外部类成员
System.out.println(radius);//访问外部类成员
}
}
public static void main() {
OutClass out = new OutClass(1.2);
InnerClass inner = out.new InnerClass();
inner.test();//内部类方法
inner.name = "my test";//内部类属性
}
}
4)成员内部类中不能存在任何static的变量和方法:
对于成员内部内并不是完全不能出现static字段的,如果你是使用final和static同时修饰一个属性字段,并且这个字段是基本类型或者String类型的,那么是可以编译通过的。原因:
非静态成员内部类要依赖外部类,所以不能有static变量;
在类加载那一章我们了解到,对于final static的变量是存放在常量池中的,不涉及到类的加载;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步