Java教程

Java中的四种内部类

本文主要是介绍Java中的四种内部类,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

如果你看过一些JDK和框架源码的话,就经常会发现一般在类的定义中,都会再定义一些其他的类,这些类也同样会被编译成字节码文件,这样的类就被叫做 内部类,按照一般的分法,大致可以分为以下四类:

  • 成员内部类
  • 局部内部类
  • 匿名内部类
  • 静态内部类
  • 成员内部类

    概念

    从名字就可以看出,这种内部类是作为类的成员而存在的,其定义位于类的内部,可以类比为成员变量来理解

    实现

    class Demo {
    
    	// ...	
    	
        class InternalClass {
            
        }
        
        // ...
        
    }
    

    约束

    首先是类定义的约束,实际上,成员内部类的类定义没有任何约束(不涉及static,因为这属于静态内部类的范畴),不仅可以将内部类声明为public、private的,甚至可以将其声明为一个abstract抽象类和interface接口,以及继承外部类也是允许的,其定义是十分宽松的

    接着是内部属性和方法,这里就有一些约束了:

    • 不能使用static来修饰任何成员内部类中的属性和方法,但可以使用private、final等其余任意修饰符
    • 可以用static final来修饰成员
    • 可以允许与外部类字段和方法重名

    也就是说,成员内部类不能存在静态属性和方法,这么做也是符合成员变量的含义

    最后是访问上的约束,这里十分重要:
    • 成员内部类也存在this指针,但是这个指针指向的是自己的引用,如果想访问外部类,需要使用 外部类名.this
    • 这个指针可以通过 外部类名.静态字段来访问外部类的静态属性或方法字段

    局部内部类

    概念

    局部内部类位于外部类成员方法的内部,可以类比局部变量

    实现

    public void publicMethod() {
            class InternalClass {
                
            }
        }
    
    

    约束

    这里的约束基本和成员内部类类似

    • 其类上不允许有任何修饰符,但是可以使用abstract将类声明为抽象类
    • 不允许将局部内部类声明为接口
    • 不允许使用static来声明成员变量和方法
    • 可以将局部内部类声明在静态方法中
    • 任意两个方法中的局部内部类可以重名

    其余的基本和成员内部类类似,把局部内部类当作成员内部类的局部变量版本就好理解了,比如也拥有外部类的指针,使用方法和成员内部类一致

    使用

    既然是局部内部类,就只能在声明类的方法处来使用,声明和使用方式如下:

    public void publicMethod() {
            class InternalClass {
    
            }
    
            InternalClass test = new InternalClass();
        }
    

    同样地,我们依然可以无条件访问内部类中定义的私有属性

    匿名内部类

    这种内部类应该是我们使用的最多的一种,有时候甚至我们已经使用过了却没有发现

    概念

    匿名内部类没有类的声明,会隐式地继承一个类或实现一个接口

    实现

    概念比较抽象,我们直接看是如何定义的,这里我们有一个接受一个对象参数的方法:

    private void privateMethod() {
            new Demo() {
                public int newVal = 20;
    
                @Override
                public void publicMethod() {
                    super.publicMethod();
                }
            };
        }
    

    这里的Demo可以换成任意一个类或者接口,你会发现这个类没有名字,所以被叫做匿名内部类

    如果Demo是一个普通类,则匿名内部类相当于这个类的子类;如果Demo是一个接口或者抽象类,则这个匿名内部类相当于接口或抽象类的实现

    约束

    想要理解匿名内部类的约束,就需要将整个匿名内部类不要当成一块程序逻辑来看,而应该当成一个对象来处理,整块匿名内部类完全可以当成一个对象,可以调用对象的方法、属性等等

    其主要的约束有以下这些:

    • 不能使用static来修饰方法和属性,但是可以有static final的属性
    • 可以使用this指针来访问本身定义的变量和继承得到的变量,也可以使用 外部类名.this
    • 指针来访问外部类中的所有属性
    • 无法在类上进行任何修饰,因为没有class定义符和类名
    • 其中定义的私有字段对外是完全可见的

    使用

    和普通对象的用法一致,举两个简单的例子:

    int val = new Demo() {
                private int newVal = 20;
    
                @Override
                public void publicMethod() {
                    super.publicMethod();
                }
            }.newVal;
            
            Demo demo = new Demo() {
                private int newVal = 20;
    
                @Override
                public void publicMethod() {
                    super.publicMethod();
                }
            };
    
    

    静态内部类

    概念

    静态内部类相当于static修饰的成员内部类,可以当作静态变量来理解

    实现

    class Demo {
    
    	// ...	
    	
        static class InternalClass {
            
        }
        
        // ...
        
    }
    
    

    约束

    这里的约束就和之前的有很大不同了,如下:

    • 可以使用任意的修饰符来修饰类、方法和属性
    • 可以访问外部类的静态方法和属性
      没错,广义上,静态内部类根本没有约束

    使用

    使用有以下两种情况:

    在外部类的方法中使用时,通过如下语句来创建内部类对象:
    InternalClass test = new InternalClass();

    在外部类之外的其他类可以通过下面的语句来创建内部类对象:
    `Demo.InternalClass test = new Demo.InternalClass();

    总结

    转载出处:https://juejin.cn/post/6844903856564862983

    这篇关于Java中的四种内部类的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!