目录
内部类的定义
把一个类定义在另一个类的内部,内部的类叫做内部类
//类Inner就是类Outer的内部类,类Outer就是类Inner的外部类
class Outer {
class Inner {
}
}
内部类的分类
根据定义位置不同将内部类分为2大类
-
定义在外部类局部位置(比如方法体或者代码块中)
-
局部内部类(定义时给出类名)
-
匿名内部类(定义时不给出类名)
-
-
定义在外部类的成员位置
-
成员内部类(不使用static修饰)
-
静态内部类(使用static修饰)
-
局部内部类
定义在外部类的局部位置,定义时给出类名
作用域:定义内部类的方法或代码块中
局部内部类可以访问外部类私有属性和方法
定义在外部类的局部位置,通常在方法中
不能添加访问修饰符,因为它是一个局部变量类型的
final可以修饰局部变量,所以可以修饰局部内部类
一般格式:
class outer {
public void dosome() {
class Inner {
}
}
}
访问方式:
-
内部类访问外部类属性
this指的是当前正在访问这段代码的对象,当在内部类中使用this指的就是内部类的对象, 为了访问外层类对象,就可以使用外层类名.this来访问,一般也只在这种情况下使用这种
外部类.this.属性名
当内部类属性和外部类属性无重名时可省略
外部类.this.
,直接使用变量名访问,因为直接使用变量名是采用就近原则class Outer { //外部类属性age private int age = 20; public void m1() { class Inner { //内部类属性age int age = 40; public void show() { System.out.println(age);//age = 40 System.out.println(Outer.this.age);//age = 20 } } Inner i = new Inner(); //存在重名变量 i.show();//40 20 //注释掉内部类里面的age i.show();//20 20 } } public static void main(String[] args) { Outer outer = new Outer(); outer.m1(); }
-
外部类访问内部类属性
在作用域中可以创建对象访问,即在内部类所在方法中创建对象访问
匿名内部类
我们在开发的时候,会看到抽象类,或者接口作为参数。
而这个时候,实际需要的是一个子类对象。
如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。
本质是继承该类或者实现接口的子类的匿名(其实系统分配了类名可以用getclass查看)对象
不能添加访问修饰符,因为它是一个局部变量
作用域:方法或者代码块等
外部不能访问
成员重名就近原则,想访问外部类的话外部类.this.成员(如果在主方法中需要创建对象,直接用对象.成员 就可以访问)
一般形式:
A a = new A(){
}
//底层是继承该类或者实现接口的子类的匿名对象
//继承类
class A$1 extends A{
}
//实现接口
class A$2 implements A{
}
A a = new A$1();
访问方式:
访问方式同局部内部类,区别是局部内部类是一个类,匿名内部类本质是一个实例化的对象
public class AnonymousIner {
int num = 90;
public void f1() {
B b = new B(){
int num = 100;
@Override
public void run() {
System.out.println("匿名内部类重写父类方法");
//访问外部类重名属性90
System.out.println(AnonymousIner.this.num);
//就近原则100
System.out.println(num);
}
};
//返回引用b的运行类型class AnonymousIner$1
System.out.println(b.getClass());
//class AnonymousIner$2
System.out.println(new B(){}.getClass());
b.run();
System.out.println(b.num);//100
}
public static void main(String[] args) {
AnonymousIner aonymousIner = new AnonymousIner();
aonymousIner.f1();
}
}
class B {
int a = 100;
public void run() {
System.out.println("B的方法执行");
}
}
//运行结果
class AnonymousIner$1
class AnonymousIner$2
匿名内部类重写父类方法
90
100
100
成员内部类
定义在外部类的成员位置
-
直接访问外部类成员
-
可以添加任意访问修饰符
-
作用域:整个类体
一般形式:
class Outer{
class MemberInnerClass{
int a = 100;
}
}
访问方式:
-
外部类访问成员内部类先创建对象,通过对象访问
new MemberInnerClass().a
-
外部其他类访问
成员内部类是以成员变量的形式存在,在外部其他类想访问这个外部类里面的内部类,首先要创建一个外部类对象,new 外部类(),通过这个对象操作外部类里面的内部类,而想操作内部类里面内容还要创建一个内部类对象new 内部类(),通过 new 外部类(). new 内部类().成员 来操作
public void f(){ System.out.println(new Outer().new MemberInnerClass().a);//100 }
-
在外部类中编写一个方法返回内部类对象
public MemberInnerClass rerurnb(){ return new MemberInnerClass().new B(); }
-
静态内部类
使用static修饰的成员内部类
-
放在外部类成员位置
-
static修饰
-
可以直接访问外部类静态成员,不能直接访问成员变量
-
可以添加任意访问修饰符
-
作用域:整个类体
一般形式:
class Outer{
static class StaticInnerClass{
int b = 100;
static int a = 10;
}
}
访问方式:
-
内部类与外部类相互访问所有静态成员用类名直接访问,非静态成员需创建对象
StaticInnerClass.a;//静态成员 new StaticInnerClass().b;//非静态成员
-
外部其它类访问静态内部类
外部类.内部类创建对象
Outer.StaticInnerClass.b;//静态成员 new Outer.StaticInnerClass().b//非静态成员
-
重名问题就近原则,访问外部类属性使用
外部类.成员
图床