Java内部类详解

内部类

含义:一个类里面声明一个类

    分类:
    	1.成员内部类
    		特点:可以调用外部类中所有的属性
    	2.静态内部类
    		特点:只能到调用外部类的静态属性
    	3.接口内部类
    		注意:接口内部类底层就是静态内部类
    	4.局部内部类
    	5.匿名内部类

内部类的应用场景1:
如果一个类的对象只在另外一个类中使用,
就可以考虑把该类变成成员内部类或者静态内部类,
如果内部类要用到外部类的所有属性就把该类变成成员内部类,
如果内部类只用到外部类的静态属性就把给类变成静态内部类

    内部类的应用场景2:
    	如果一个类的对象只在另外一个类的方法中使用,就可以考虑把该类变成局部内部类,一般不使用这种设计思想
    
    内部类的应用场景3:
    	如果一个类的对象只在接口中使用,就可以考虑把该类变成接口内部类,一般不使用这种设计思想
    
    内部类的应用场景4:
    	抽象类子类的对象或者是接口实现类对象只使用到一次,就可以考虑使用匿名内部类

成员内部类

理解

成员内部类,和实例属性 实例方法 动态代码块 构造器 是同一级别的事物,实例级别内容。

定义
//外部类
public class Foo {
    //内部类:成员内部类
    class Boo{
    }
}
成员内部类成分
//外部类
public class Foo {
    //内部类:成员内部类
    class Boo{
        int age; // OK 实例属性
        static int name; //ERROR  不能定义静态属性
        // OK 普通代码块
        {       
            
        }
        // ERROR 不可以定义
        static {
            
        }
        //OK 构造器
        public Boo(){
            
        }
        //OK 实例方法
        public void m1(){
            
        }
        // ERROR 报错不可定义静态方法
        public static void m2(){
            
        }
    }
}

不可以定义 static 相关内容,除此都可以。

成员访问规则
内部类访问外部

可以访问 实例信息和静态信息(全部),如果内部类访问外部类的同名属性默认,就近原则,通过 外部类名.this.xxx 可以强制区分外部类属性。

//外部类
public class Foo {
    int fmoney;
    static int fheight;
    public void f1(){

    }
    public static  void f2(){

    }
    //内部类:成员内部类
    class Boo{
        int age; //实例属性
        public void m1(){ //实例方法
            System.out.println( fmoney ); //OK 可直接访问
            System.out.println( fheight); //OK 可直接访问
            f1();                         //OK 可直接访问
            f2();                         //OK 可直接访问
        }
    }

}
外部类访问内部

这个简单呀,当一个类使用即可,先创建对象,再访问实例属性和实例方法。

//外部类
public class Foo {
    int fmoney;
    static int fheight;
    public void f1(){
        Boo boo = new Boo();   // 1 创建对象
        boo.m1();              // 2 对象来访问即可
    }
    public static  void f2(){
    }
    //内部类:成员内部类
    class Boo{
        int age; //实例属性
        public void m1(){ //实例方法
        }
    }
}
其他位置访问内部类
  1. 需要创建对象然后使用
    public static void main(String[] args) {
        //分开来写
        Foo foo = new Foo();
        Foo.Boo boo1=  foo.new Boo();
        //一步到位
        Foo.Boo boo2 = new Foo().new Boo();
        boo2.xx();
    }
  1. 通过对象引用调用属性和方法。

内 部类单独使用,声明类型的时候需要带外部类名一起声明。比如 Foo.Boo

小细节

内部类也会生成单独的字节码文件,只是这个文件名规则为: 外部类名+$+内部类名.class

img

成员内部类使用案例
package case2;

public class Car {
    //名字
    String brand;
    public Car(String brand){
        this.brand=brand;
    }
    //汽车行驶方法 需要发动机提供动力
    public void run(){
        System.out.println(brand+"启动");
        Engine engine = new Engine();
        engine.zhuan();
    }
    //引擎,对外不公开,专门为外部类设计,为外部类提供服务
    private class Engine {
        public void zhuan(){
            System.out.println("发动机运行");
        }
    }
}
package case2;
// 内部类使用案例
public class TestCar {

    public static void main(String[] args) {
        Car car = new Car("宝马");
        car.run();
    }
}

静态内部类

理解

静态内部类,和静态属性 静态方法 静态代码块 是同一级别的事物,是类级别内容。

定义
public class Foo {
    //静态内部类
    static class Boo{
        
    }
}
定义成分
public class Foo {
    static class Boo{
        int age ;           // 实例属性  OK 
        static int money;   // 静态方法  OK 
                            // 构造器 OK 
        public Boo(){
            
        }
                            // 实例方法 OK 
        public void m1(){}
                            // 静态方法 OK 
        public static void m2(){}
                            // 普通代码块OK 
        {
            
        }
                           // 静态代码块 OK 
        static {
        }
    }
}

从定义成分上看,几乎等价与一个普通外部类

成员访问规则
内部类访问外部类

只能访问到静态内容(静态属性 静态方法)

外部类访问内部类

就是一个普通类的访问方式:

  1. 通过类名访问静态属性和方法
  2. 通过对象访问实例属性和方法
其他位置访问内部类

就是一个普通类的访问方式:

  1. 通过类名访问静态属性和方法
  2. 通过对象访问实例属性和方法

方法内部类

理解

方法内部类,定义外部类的方法中,和方法的局部变量同级别。

定义
public class Foo {
    public void f1(){
        int age = 10;
        //方法内部类
        class Boo{
            
        }
    }
}
定义成分
 public  void f1(){
        int age = 10;
         // 内部类
         class Boo{
             //实例属性 OK
             int age;    
            
            // 构造器 OK 
            public Boo(){
                
            }
            // 动态代码块 OK 
            {
                 
            }
            public void m1(){ // 实例方法 OK
                
            }
        }
    }

只能定义实例相关信息,不可定义静态内容,且不可添加访问权限。

成员访问规则
内部类访问外部类

可以直接访问静态和实例的信息。

外部类访问内部类

就是一个普通类的访问方式:

  1. 通过对象访问实例属性和方法 ,只能在内部类所在方法中使用
细节面试题

局部内部类访问 所在方法的 局部变量,要求这个变量是final修饰的,在JDK7必须强制声明为final,JDK8中无需声明,但是编译器依然要求它是一个final。

为什么呢? 需要延长局部变量的生命周期,保证对象使用该变量时,它是存在的,通过final 修饰的变量进入常量池,会一直保存。

匿名内部类

理解

添加访问权限。

成员访问规则
内部类访问外部类

可以直接访问静态和实例的信息。

外部类访问内部类

就是一个普通类的访问方式:

  1. 通过对象访问实例属性和方法 ,只能在内部类所在方法中使用
细节面试题

局部内部类访问 所在方法的 局部变量,要求这个变量是final修饰的,在JDK7必须强制声明为final,JDK8中无需声明,但是编译器依然要求它是一个final。

为什么呢? 需要延长局部变量的生命周期,保证对象使用该变量时,它是存在的,通过final 修饰的变量进入常量池,会一直保存。

匿名内部类

理解

没有名字的内部类,是一种特殊的局部内部类。它是把类的定义和对象创建合二为一。匿名内部类只能创建一次对象。匿名内部类必须是某个接口的实现类或者是某个类的子类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值