java内部类的简单理解

内部类

在Java中可以将一个类定义在另一类或方法里面,这样的类称为内部类。广泛意义上内部类一般包括四种:成员内部类、局部内部类、匿名内部类、静态内部类

// 外部类outer
public class Outer{
    // 内部类Inner
    class Inner{ }
}

1. 成员内部类

成员内部类是最普通的内部类,也称作普通内部类

成员内部类当成Outer的成员信息存在
  1. 可以是任何的访问修饰符

  2. 内部类的内部不能有静态信息

  3. 内部类也是类,该继承继承,该重写重写,该重载重载,this和super随便用

  4. 外部类如何访问内部类信息,必须new之后打点访问。

  5. 内部类可以直接使用外部类的任何信息,如果属性或者方法发生冲突,调用外部类.this.属性或者方法。

  6. 其它类如何访问内部类:

    Outer outer = new Outer(); Outer.Inner inner = outer.new Inner();

    Outer.Inner inner = new Outer().new Inner();

  7. 内部类和外部类都会编译成独立的class文件

public class Outer {
    String outer0 = "外部类的公共属性" ;
    private String  outer1 = "外部类的私有属性" ;
    private static String outer2 = "外部类的静态属性" ;
    String same = "外部" ;

    public void outerMethod(){
        System.out.println("外部类的成员方法");
    }
    public static void outerStaticMethod(){
        System.out.println("外部类的静态方法");
    }

    class Inner {
        String same = "内部" ;
        // 构造方法
        Inner(){        }
        // 内部类的成员方法,访问外部类的信息
        public void innerShow(){
            System.out.println("相同的属性名:"+" : "+same);
            System.out.println("访问外部类公共属性"+" : "+outer0);
            System.out.println("访问外部类私有属性"+" : "+outer1);
            System.out.println("访问外部类静态属性"+" : "+outer2);
            outerMethod();
            outerStaticMethod();
        }
    }
    // 外部类访问内部类的方法
    public void show(){
        Inner inner = new Inner();
        inner.innerShow();
    }
}

class Test{
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.innerShow();
    }
}
/**运行结果:
相同的属性名: : 内部
访问外部类公共属性 : 外部类的公共属性
访问外部类私有属性 : 外部类的私有属性
访问外部类静态属性 : 外部类的静态属性
外部类的成员方法
外部类的静态方法
/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVCJuWw1-1597749723554)(Java.assets/image-20200818163559463.png)]

2.静态内部类

静态内部类就是在成员内部类多加了一个static关键字。静态内部类只能访问外部类的静态成员变量和方法(包括私有静态)

和成员内部类对比

  1. 内部类可以包含任意信息

  2. 静态内部类的方法只能访问外部类的static关联的信息

  3. 调用

    Outer.Inner inner = new Outer.Inner();
    inner.innerShow();// inner.属性或方法
    
  4. 访问内部类的静态信息,直接 Outer.Inner.静态信息;

  5. 静态内部类可以独立存在,不依赖于其他外围类。

/**
 * 外部类、内部类定义
 */
public class Outer {
    private int outerVariable = 1;
    /**
     * 外部类定义的属性(重名)
     */
    private int commonVariable = 2;
    private static int outerStaticVariable = 3;
    static {
        System.out.println("Outer的静态块被执行了……");
    }
    /**
     * 成员方法
     */
    public void outerMothod() {
        System.out.println("我是外部类的outerMethod方法");
    }
    /*
     * 静态方法
     */
    public static void outerStaticMethod() {
        System.out.println("我是外部类的outerStaticMethod静态方法");
    }


    /**
     * 静态内部类
     */
    public static class Inner {
        /**
         * 成员信息
         */
        private int innerVariable = 10;
        private int commonVariable = 20;

        static {
            System.out.println("Outer.Inner的静态块执行了……");
        }
        private static int innerStaticVariable = 30;
        /**
         * 成员方法
         */
        public void innerShow() {
            System.out.println("innerVariable:" + innerVariable);
            System.out.println("内部的commonVariable:" + commonVariable);
            System.out.println("外部静态属性 : " + outerStaticVariable);
            outerStaticMethod();
        }
        /**
         * 静态方法
         */
        public static void innerStaticShow() {
            //被调用时会先加载Outer类的静态方法
            outerStaticMethod();
            System.out.println("innerStaticShow : " + outerStaticVariable);
        }
    }
    /**
     * 外部类的内部如何和内部类打交道
     */
    public static void callInner() {
        System.out.println(Inner.innerStaticVariable);
        Inner.innerStaticShow();
    }
}
/** 运行结果:
Outer.Inner的静态块执行了……
innerVariable:10
内部的commonVariable:20
Outer的静态块被执行了……
外部静态属性 : 3
我是外部类的outerStaticMethod静态方法
我是外部类的outerStaticMethod静态方法
innerStaticShow : 3
/

内部的静态代码块先被加载

其他类使用内部类

public class Test{
    public static void main(String[] args) {
        // 访问静态内部类的静态方法,Inner类被加载,此时外部类未被加载,独立存在,不依赖于外围类
        Outer.Inner.innerStaticShow();
        // 访问静态内部类的成员方法
        Outer.Inner inner = new Outer.Inner();
        inner.innerShow();
    }
}

3.局部内部类

局部内部类就是定义在代码块内的一个内部类。比如在方法里面定义一个内部类,就是局部内部类。

局部内部类的作用范围仅仅在他所在的代码块里。局部内部类不能被public ,protected,private以及static修饰,但是可以被final修饰。

可以随意的访问外部类的任何信息

public class Outer {
    private int num = 2 ;
    public void test(){
        class Inner{
            final String innerStr = "inner";
            public void show(){
                System.out.println(num);
            }
        }
        new Inner().show();// 仅限于在内部类所在的方法内使用
    }
}

4.匿名内部类

匿名内部类:顾名思义就是没有名字的类。

一般遇到下面这种情况都会考虑到使用匿名内部类:
当一个内部类需要继承或者实现,而且只使用一次的时候,可以考虑使用匿名内部类。调用的时候直接使用父类的无参构造,并重写父类方法。

public class Outer {
    public static void main(String[] args) {
        new Test(){
            @Override
            public void aa() {
                
            }
        }.aa();
    }
}
interface Test{
    void aa();
}
  1. 匿名内部类是没有访问修饰符的。
  2. 使用匿名内部类时,这个new之后的类首先是要存在的,其次我们要重写new后的类的某个或某些方法。
  3. 匿名内部类访问方法参数时也有和局部内部类同样的限制。
  4. 匿名内部类没有构造方法。

内部类使用场景

**场景一:**当某个类除了它的外部类,不再被其他的类使用时。我们说这个内部类依附于它的外部类而存在,可能的原因有:1、不可能为其他的类使用;2、出于某种原因,不能被其他类引用,可能会引起错误。等等。这个场景是我们使用内部类比较多的一个场景。(内部类可以看成代码隐藏机制)
**场景二:**当我们希望一个类必须继承多个抽象或者具体的类时,就只能用内部类来实现多重继承

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值