四种内部类,(Inner Class)

内部类: 定义在内部的类,不一定非得是定义在类的内部, 可以分为4种类型。
第一: 静态内部类(定义在类中)

  1. 静态的内部类与其外部类是编译成 两个.class文件 的,注意的是外部类是不可以定义为静态的。
    为什么外部的类不可以定义为静态的
    解释:静态类是没有实际意义的,而且运行初始化还要占用大量内存,而且假如有静态类,不能被重写,不能创建对象,没啥实际意义。
    备注:其实只需要定义静态变量、静态方法、静态内部类等完全可以满足需求的。
  2. 只能访问外部类的静态成员变量与静态方法,
    为什么静态的只能访问静态的?
    解释: 静态的变量或者方法是在类被加载的时候被构造的,而非静态的则是在生成对象的时候创建的,当在静态里面调用非静态的时候,可能非静态的还没有没创建,会发生非法访问。所以静态的只能访问静态的。

  3. 生成静态内部类对象的方式为:
    OuterClass.InnerClass inner = new OuterClass.InnerClass();

// B是A的静态内部类
public  class A{
    public static class B{
    }
}

第二: 成员内部类(内部的非静态的类)(定义在类中)
1. 可以访问外部类的静态与非静态的方法与成员变量。
2. 生成成员内部类对象的方式为: (和静态内部类是不同的)
OuterClass.InnerClass inner = new OuterClass().new InnerClass();

为啥这样写:
因为是非静态的类,可以类比成非静态的一个成员方法,必须通过一个实例化的对象来调用,而静态的内部类可以直接通过类名来调用,所以静态的内部类可以直接通过 外部类名.内部类名 调用 ; 而成员内部类必须通过 new 外部类().内部类() 调用。 通过外部类的一个对象来调用内部类

  1. 也是生成两个.class 文件
  2. 若想在局部内部类中访问外部类的成员变量,语法 OuterClass.this.a;
// B是A的成员内部类, 与静态内部类的区别是有无static关键字
public class A{
    private  int  a;
    public class B{
       private  int  a;
       public  void set(){
            a= A.this.a;  // 内部类中 使用 OuterClass.this.a; 访问外部的成员 
       }
    }
}

第三: 局部内部类(定义在方法中的)用的比较少

类似于一个局部变量,不能定义成 public private,protected 访问修饰符的变量, 原因是局部变量前面不能带有访问修饰符,访问修饰符只能修饰成员变量。

我们是没有办法在外部类中使用的,只能在其所定义的成员方法内使用

局部内部类中是不能访问外部类的成员或者方法的,只能访问方法中声明的 final类型的变量

第四: 匿名内部类 (Anonymous inner class )

内部类,但是没有名字 没有名字就意味着没有构造方法, 是一种特殊的局部内部类。

匿名内部类会隐式地继承一个父类或实现一个接口。最重要的特点

//  一个测试类
public class AnonymousInnerClass {
    @SuppressWarnings("deprecation")
    public String getTime(Date  date){
        return date.toLocaleString();
    }

    public static void main(String[] args) {
        AnonymousInnerClass  annoymousClass  =  new AnonymousInnerClass();
        // 传给 getTime方法中的对象是一个Date类的对象
        String  str = annoymousClass.getTime(new Date());

        // 在这里new Date(){  } 就是定义了一个内部类,
        // 这个内部类继承了 Date 这个类,但是没有重写 Date类中的任何方法
        //  然后传给 getTime方法中的对象是一个继承了Date类的子类的对象
        // 可以看生成的.class 文件,会多了一个,而且内部类因为没有名字,所以就 $num  以数字的方式表示了内部类
        String  strInner = annoymousClass.getTime(new Date(){  } );
        System.out.println(str);
        System.out.println(strInner);       

    }
}

通常也是用在方法内的,一般作为参数传递进去

Swing 使用匿名内部类实现了监听接口,为一个事件添加一个监听器,适用于 该内部类实现的功能只会被使用一次,或者被一个对象使用的情况,不必要再为其单独的写一个类。

public  static  void  main (){
    JFrame  frame  =  new JFrame("JFrame");
    JButton  button  = new JButton("click me");
    // 使用内部匿名类的形式为button添加了一个监听器,
    // 有人可能有疑问ActionListener不是一个接口吗?怎么还可以new 出来一个对象,这是内部匿名类的机制,这个地方创建的对象是一个实现了ActionListener接口的具体的实例的对象,并不是一个ActionListener接口对象。
    button.addActionListener (new  ActionListener(){
            public  void  actionPerformed(ActionEvent e){
                   System.out.println("welcome");
            }
     })
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值