内部类

把一个类放在另一个类内部定义,即为内部类。

一、非静态内部类

二、静态内部类

三、局部内部类

四、匿名内部类

其中前面两个是类成员,我们可以称作为成员内部类,既然作为成员,那么就像成员变量一样,可以使用private、protected、public、默认、static这样的修饰符。

-----------------------------------------------------------------------------------------------------------------

接下来我们依次进行讨论:

  • 非静态内部类:
  1. 可以访问外部类的成员变量,不用管是private还是啥的,外部类的一切都可以访问;外部类不可以直接使用非静态内部类的成员,如果要使用则必须显示创建非静态内部类对象来访问,可以看3。

        原因:非静态内部类对象里,保存了一个他所寄生的外部类对象的引用。

    2. 对于外部类成员变量、非静态内部类成员变量、非静态内部类方法的局部变量同名的情况

       外部类名字.this.成员变量名       this.成员变量名         局部变量名

public class Outer{
    private String prop="外部prop";
    private class Inner{
        private String prop="内部prop";
        public void info(){
            String prop="方法prop";
            System.out.println(prop);
            System.out.println(this.prop);  
            System.out.println(Outer.this.prop);
        }
    }
}

3. 不允许在外部类的静态成员中直接使用非静态内部类

class Outer{
    class Inner{
        private int prop=5;
       //private static int x;//错误的,不允许在非静态内部类定义任何静态的东西
    }
    public void test1(){
        System.out.println(new Inner().prop);
    }
    public static void test2(){
        //System.out.println(new Inner().prop);//错误的,不允许在外部类的静态成员中直接使用非静态内部类
    }
}
4. 编译会生成两个文件:Outer.class  Outer$Inner.class

5. 非静态内部类必须寄生在外部类对象里,而外部类对象则不必一定有非静态内部类对象寄生其中。这也就解释了为什么外部类对象不可以访问非静态内部类成员,因为可能非静态内部类对象根本就不存在。

  • 静态内部类:属于外部类本身,而不是外部类的某个对象

1. 只能访问外部类的静态成员(类成员),而不能访问实例变量

2. 静态内部类不是寄生在外部类对象,而是寄生在外部类的类本身当中。当静态内部类对象存在的时候,不一定存在一个被他寄生的外部类对象,他只有外部类的引用,没有外部类对象的引用。

3. 外部类仍然不可以直接访问内部类的成员。如果要使用则必须显示创建非静态内部类对象来访问(针对实例成员) 或者 使用内部类的类名来访问(针对静态成员)。

总结一句话:

静态内部类里面可以定义静态的和非静态的成员变量、方法...,可以随意访问外部类的静态的一切

非静态内部类只能定义非静态的成员变量、方法...,可以随意访问外部类的一切

外部类访问静态内部类,对于静态的,用类名.XXX, 对于非静态的,用new 内部类名().XXX

外部类访问非静态内部类,因为非静态内部类根本没有非静态的东东了,当然就是用new 内部类名().XXX

-----------------------------------------------------------------------------------------------------------------

在外部类的外面使用内部类:

非静态内部类: 外部类名.内部类名 变量名=new 外部类名().new 内部类名();

静态内部类:       外部类名.内部类名 变量名=new 外部类名.内部类名();

补充:如果一个类继承了非静态内部类,那么必须让子类构造器可以调用父类构造器,调用非静态内部类的构造器的时候,必须存在一个外部类对象。

比如:

public class SubClass extends Out.In{
    public SubClass(Out out){
        out.super();//调用父类的构造器,父类是Out类的非静态内部类
    }
}

创建非静态内部类In对象和他的子类都应该持有Out对象的引用,只是他们传入的方式不同:

当创建非静态内部类In类的对象的时候,必须通过Out对象来调用new关键字;

当创建SubClass类的对象时,必须使用Out对象作为调用者来调用In类的构造器。

-----------------------------------------------------------------------------------------------------------------

  • 局部内部类:在方法里定义,不能使用static修饰

      外部类的名字$N局部内部类的名字.class

  • 匿名内部类:匿名内部类不能是抽象类;不能定义构造器,但匿名内部类可以定义初始化块

被匿名内部类访问的局部变量,可以用final修饰,也可以不用final修饰,但必须按照有final修饰的方式来用。也就是一次赋值之后,以后不可以再次重新赋值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值