内部类
一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类
特点
可以直接访问私有属性,并且可类与类之间的包含关系
语法
class outer{ //外部类
class inner{ //内部类
}
}
class Other{ //外部其他类
}
分类
定义在外部类的局部位置上(通常在方法中 ,但也可在代码块中 )
- 局部内部类
- 匿名内部类(重点)
定义在外部类的成员位置上
- 成员内部类(无static修饰)
- 静态内部类(使用static修饰)
(一)局部内部类
语法
class outer{ //外部类
{
class inner0{ //声明在代码块中的局部内部类
}
}
权限修饰符 关键字 返回类型 方法名(参数列表){
class inner1{ //声明在方法中的局部内部类
}
}
}
使用细节
-
可以访问外部类的所有成员(包括私有)
-
不能添加访问修饰符。局部内部类的地位和局部变量等同,局部变量是不能添加修饰符(final除外)的,局部变量和局部内部类都可以用final修饰
-
作用域:只能在所定义位置的方法体内或代码块中使用
-
内部类可以直接访问外部类的成员
-
外部类可在方法中实例化内部类对象,通过对象.方法访问内部类的成员
class test{ public static void main(String[] args){ Outer o = new Outer(); o.k(); //输出 内部类... } } class outer{ public void k(){ class Inner{ //局部内部类 public void j(){ System.out.println("内部类..."); } } Inner n = new Inner(); n.j(); } }
-
外部其他类不能访问局部内部类
-
如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)来访问(外部类名.this本质上是外部类的对象,具体是哪个对象则要看是谁调用了该内部类所在的方法)
(二)匿名内部类
匿名内部类仍然是定义在外部类的局部位置,比如方法或代码块中
匿名内部类没有名字(显式没有名字,但实际上系统为它分配了名字(外部类名$1))
匿名内部类同时还是一个对象
语法
new 类或接口(参数列表){
类体
};
使用情景
某些类在开发过程中只会使用一次,这时对于只使用一次的类进行类的定义就会显得有些繁琐,因此便采用匿名内部类的方式来使用这些只会被使用一次的类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xIjD4AxM-1641113551327)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102144322561.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q37lf97F-1641113551331)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102144441118.png)]
基于接口的匿名内部类
IA inner = new IA(){
public void eat(){
sout("吃...");
}
}
implement IA{
public void eat();
}
解释:inner的编译类型是Inner,而运行类型则是匿名内部类。当执行IA(){…}实际上在系统内部自动声明了一个实现IA接口的匿名内部类,之后便创建了这个匿名内部类的实例,并将其地址赋给inner
基于类的匿名内部类
思想和基于接口的匿名内部类大致相同
Animal animal = new Animal("小黄狗"){
public void eat(){
sout("吃骨头...");
}
}
class Animal{
String name;
public void eat();
}
解释:animal的编译类型是Animal,而允许类型是匿名内部类。当执行Animal(…){…}时系统内部将自动声明一个继承Animal类的匿名内部类,之后便创建了这个匿名内部类的实例,并将其地址赋给animal
使用细节
- 可以访问外部类的所有成员,包括私有
- 不能添加访问修饰符
- 作用域:方法体内或代码块中
- 外部其它类不能访问匿名内部类
- 如果外部类和匿名 内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)来访问
具体实践
当做实参直接传递
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PFLmugrd-1641113551332)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102153556251.png)]
(三)成员内部类
定义在外部类的成员位置,并且没有static修饰
使用细节
-
可以直接访问外部类的所有成员,包括私有
-
可以添加任何访问修饰符(public、static、缺省、private),其地位等同于类成员
-
作用域:整个类体
-
外部类访问成员内部类,需要在外部类的方法中实例化成员内部类
-
如果外部类和成员内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)来访问
-
外部其它类也可访问成员内部类
-
通过外部类的对象实例化一个成员内部类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rNM4mzM5-1641113551334)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102160249786.png)]
-
在外部类中编写一个方法返回成员内部类的实例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzgv9QiB-1641113551335)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102160435532.png)]
-
(四)静态内部类
定义在外部类的成员位置,被static修饰
使用细节
-
可以直接访问外部类的所有静态成员,包括私有,但不能直接访问非静态成员(地位等同于静态方法)
-
可以添加任何访问修饰符(public、static、缺省、private),其地位等同于类成员
-
作用域:整个类体
-
外部类访问静态内部类,需要在外部类中的方法中 实例化静态内部类
-
如果外部类和静态内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.成员)来访问
-
外部其它类也可访问静态内部类
-
通过类名直接访问(静态)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hY2b000D-1641113551336)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102162430444.png)]
-
在外部类中编写一个方法返回静态内部类的实例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eNFvCYGq-1641113551338)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102162854928.png)]
-