目录
1.成员内部类(定义在类中,与类中的成员变量一起)成员内部类中不能有静态变量,但是可以有静态常量,用static final 修饰的常量。
2.局部内部类(定义在方法中的内部类,局部内部类前面不能加private或public,其范围就是方法的范围)
3.静态内部类(静态内部类的对象可以直接生成 外部类.内部类 in=new 外部类.内部类() )
1.成员内部类(定义在类中,与类中的成员变量一起)成员内部类中不能有静态变量,但是可以有静态常量,用static final 修饰的常量。
(在外部类中访问局部内部类,创建对象 Outer.Inner in=new Outer().new Inner() )
//成员内部类不能有静态变量,但可以访问外部类的所有成员
public class Outer {
private int i=10;
private static int j=20;
private int k=30;
public static void outerF1(){
}
public void outerF2(){
}
//成员内部类
class Inner {
private int i=40; //内部类中可以和外部类的实例变量共存
static int n=50; //用静态修饰的变量是不允许的
static final int m=60;//用静态修饰的常量允许
void inner01(){
System.out.println(i); //访问内部类中的i
System.out.println(this.i); //访问内部类中的i
System.out.println(Outer.this.i); //访问外部类中的i
System.out.println(j);//内部类和外部类变量没同名,可以直接访问外部类变量
System.out.println(k);
}
}
//外部类的非静态方法访问内部类
public void test01(){
Inner inner=new Inner(); //直接创建内部类的对象
inner.inner01();
}
//外部类静态方法访问内部类
public static void main(String[] args) {
Outer outer=new Outer(); //1.先创建外部类对象
Inner inner=outer.new Inner(); //2.通过外部类对象创建内部类对象
inner.inner01(); //3.引用方法
Outer.outerF1();
outer.outerF2();
}
}
java的成员内部类中为什么不能有静态变量?
Java的成员内部类是一个嵌套在另一个类中的类,它可以访问外部类的成员和方法。由于成员内部类依赖于外部类的实例,因此不能包含静态成员或静态方法。具体来说,成员内部类的实例始终与外部类的实例相关联。因此,在成员内部类中声明静态变量会导致矛盾:它们无法区分哪个外部类的实例应该包含该静态变量。同样,成员内部类中的静态方法也无法访问外部类的实例变量,因为它们是静态的并且不依赖于外部类的实例。但是,成员内部类可以有静态常量(即使用final修饰的变量)。这是因为静态常量的值在编译时就已经确定,并且与外部类实例无关。静态常量在成员内部类和外部类之间共享,并且可以通过外部类名访问,如Outer.Inner.CONSTANT。由于成员内部类实例与外部类实例相关联,因此它们不能包含静态成员或静态方法,但可以包含静态常量。
成员内部类优点:
1.内部类作为外部类的成员可以访问外部类的私有成员和属性
2.内部类中定义外部类不可访问的属性(私有属性),这样就有了比外部类的private更小的访问权限。
这两个类编译成功之后会出现Outer.class和Outer$Inner.class的这样两个编译文件。
2.局部内部类(定义在方法中的内部类,局部内部类前面不能加private或public,其范围就是方法的范围)
(我们想创建一个类解决问题,但是又不想让这个类公开,所以就有了局部内部类)
局部内部类中不能定义静态变量,可以访问外部类的局部变量(方法中定义的变量),但必须是用final修饰的。
public class Outer01 {
private int i=10;
private int a=20;
private void m2(){}
public void ml01(){
//局部内部类
final class Inner01{ //局部内部类不能被private和public修饰符修饰,但是可以被final修饰
private int a=30; //可以定义和父类相同的变量
public void f1(){
m2(); //可以直接调用父类的方法
//如果外部类和内部类的成员重名,默认使用就近原则,如果想访问外部类的成员采用(外部类.this.成员)
System.out.println(i);
System.out.println(a);
System.out.println(Outer01.this.a);
}
}
//如果外部类想访问局部内部类,只能在内部类所在的这个方法中创建对象
Inner01 inner01=new Inner01();
inner01.f1();
}
public static void main(String[] args) {
Outer01 outer01=new Outer01();
outer01.ml01();
}
}
3.静态内部类(静态内部类的对象可以直接生成 外部类.内部类 in=new 外部类.内部类() )
public class Outer02 {
private static int i=10;
private int j=20;
public static void outerF1(){}
private void outerF2(){}
//静态内部类可以用private、public、protected修饰
//静态内部类可以定义静态和非静态成员
static class Inner02{
private int m=20;
private static int n=30;
void InnerTest(){ //静态内部类只能访问外部类的静态成员和静态方法
System.out.println(i);
outerF1();
}
}
public void outerF3(){
//外部类访问内部类的静态成员: 内部类.成员
System.out.println(Inner02.n);
//外部类访问内部类的非静态成员 通过实例化内部类来访问内部类的非静态成员
Inner02 inner02=new Inner02();
System.out.println(inner02.m);
}
public static void main(String[] args) {
Outer02 outer02=new Outer02();
outer02.outerF3();
//生成静态内部类不需要通过外部类对象生成,这是静态内部类和成员内部类的区别
Outer02.Inner02 inner02=new Outer02.Inner02();
inner02.InnerTest();
}
}
4.匿名内部类
匿名内部类是没有类名的特殊内部类,适合创建只使用一次。匿名内部类需要继承一个已有的父类或实现一个接口。由于匿名类本身没有名字,也不存在构造方法,也不能包含静态成员。
new 父类名/接口名( ) { }
public class Test04 {
public static void main(String[] args) {
//这个整体实现接口就是匿名内部类
MyInterface mi=new MyInterface() {
@Override
public void say() {
System.out.println("实习接口问好");
}
};
//这个整体也是匿名内部类
MyClass01 mc=new MyClass01(){
public void hello(){
System.out.println("匿名子类"+age);
}
};
mc.age=20;
mc.hello();
}
}
interface MyInterface{
void say();
}
class MyClass01 {
public int age;
public void hello(){
System.out.println("父类方法");
}
}