一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他的类称为外部类。
类的五大成员:属性、方法、构造器、代码块、内部类
内部类最大的特点的就是直接访问私有属性,并且可以体现类鱼类之间的包含关系。
基本语法:
class Outer{ //外部类
class Inner{ //内部类
}
}
class Other{ //其他类
}
内部类的分类:
定义在外部类局部位置上(比如方法内)
①局部内部类(有类名)
②匿名内部类(没有类名)
定义在外部类的成员位置上
①成员内部类(没有static修饰)
②静态内部类(使用static修饰)
---------------------------------------------------------------------------------------------------------------------------------
①局部内部类的使用
说明:局部内部类是定义在外部类的局部位置,比如:方法中,并且有类名
1、可以直接访问外部类的所有成员,包含私有的。
2、不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量不能使用修饰符。但是可以使用final修饰,因为局部变量也可以使用final。
3、作用域:仅仅在定义它的方法或代码块中。
4、局部内部类----访问---外部类的成员:直接访问。
5、外部类----访问---局部内部类的成员:创建对象,再访问。(必须在作用域中)
class Outer{
private int n=10;
private void x(){}
public void m(){
// 不能添加访问修饰符,因为它的地位就是一个局部变量。
public class Inner{ //报错
public void f(){
// 可以直接访问外部类的所有成员,包含私有的。
System.out.println("n="+n);
x();
}
}
// 外部类----访问---局部内部类的成员
// 创建对象,再访问。(必须在作用域中,方法中)
Inner inner=new Inner();
inner.f();
}
}
6、外部其他类不能访问局部内部类。(因为局部内部类地位是一个局部变量)
7、如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以用 外部类名.this.成员 去访问。
public static void main(String[] args) {
Outer outer=new Outer();
outer.m();
}
class Outer{
private int n=10;
public void f(){
System.out.println("我是外部类");
}
public void m(){
// 不能添加访问修饰符,因为它的地位就是一个局部变量。
class Inner{
int n=80;
public void x(){
System.out.println("n="+n); // 输出80
System.out.println("n="+Outer.this.n); //输出10
// 可以直接访问外部类的所有成员,包含私有的。
}
}
// 外部类----访问---局部内部类的成员
// 创建对象,再访问。(必须在作用域中,方法中)
Inner inner=new Inner();
inner.x();
}
}
---------------------------------------------------------------------------------------------------------------------------------
②匿名内部类的使用
基本语法:
new 类或者接口(参数列表){
//类体
};
①本质还是类 ②内部类 ③该类没有名字 ④同时还是一个对象
说明:匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名
基于接口的匿名内部类:
需要重写接口的抽象方法
public static void main(String[] args) {
Outer outer=new Outer();
outer.f();
}
class Outer {
public void f() { //外部类的方法中
//匿名内部类
//利用接口并创建对象
A a=new A() {
//编译类型 A,运行类型:Outer$1(系统默认)
@Override
public void m() {
System.out.println("匿名内部类");
}
};
//对象调方法
a.m();
}
}
//接口
interface A{
public void m();
}
匿名内部类也是一个对象,所以可以直接调用方法:
new A() {
//编译类型 A,运行类型:Outer$1(系统默认)
@Override
public void m() {
System.out.println("匿名内部类");
}
}.m(); //直接调用
结果:
基于类的匿名内部类写法一样
注意点和内部类一样。
例题:
代码:
public static void main(String[] args) {
phone p=new phone();
p.alarm(new Bell() {
@Override
public void ring() {
System.out.println("打铃了");
}
});
}
interface Bell{
void ring();
}
class phone{
public static void alarm(Bell bell){
bell.ring();
}
}
结果:
---------------------------------------------------------------------------------------------------------------------------------
③成员内部类
成员内部类是定义在外部的成员位置,并且没有static修饰。
1、可以直接访问外部类的所有成员,包含私有的。
2、可以任意添加访问修饰符,因为它的位置就是一个成员。
public static void main(String[] args) {
A a =new A();
a.t();
}
class A{
private int age=24;
public String name="张三";
//成员内部类
public class B{ //可以任意添加访问修饰符
public void show(){
System.out.println("姓名为:"+name+", 年龄为:"+age);
}
}
//写方法
public void t(){
//使用成员内部类
B b=new B();
b.show();
}
}
输出结果为:
3、作用域:和外部类的其他成员一样,为整个类体。
4、成员内部类访问外部类:直接访问。
5、外部类访问内部类 :创建对象,再访问
6、外部其他类访问成员内部类
---------------------------------------------------------------------------------------------------------------------------------
④静态内部类的使用
静态内部类是定义在外部类的成员位置,并且有static修饰
1、可以直接访问外部类的所有静态成员,包含私有的,但是不能直接访问非静态成员。
2、可以添加任意访问修饰符,相当于一个成员。
3、作用域:同其他的成员,为整个类体。
4、静态内部类访问外部类:直接访问所有的静态成员
5、外部类访问内部类:创建对象,再访问。
6、外部类访问静态内部类