内部类总结

  内部类的定义:可以将一个类的定义放在另一个类的定义内部,这就是内部类。

  内部类与组合是完全不同的概念。

内部类基础

  在java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。静态内部类又叫做嵌套类。

  1. 成员内部类

      是普通的内部类形式

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
        public class Circle {
        double radius = 0;
    
        public Circle(double radius)
        {
            this.radius = radius;
        }
    
        class Draw{
            public void drawShape(){
                System.out.println("drawshape");
            }
        }
    }
    

      成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

      不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

    1
    2
    
        外部类.this.成员变量
        外部类.this.成员方法
    

      内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。

  2. 局部内部类

      局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者作用域内。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    class People{
        public People() {
    
        }
    }
    
    class Man{
        public Man(){
    
        }
    
        public People getWoman(){
            class Woman extends People{   //局部内部类
                int age =0;
            }
            return new Woman();
        }
    }
    

      注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

  3. 匿名内部类

      匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

  4. 静态内部类

      静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    public class Test {
        public static void main(String[] args)  {
            Outter.Inner inner = new Outter.Inner();
        }
    }
    
    class Outter {
        public Outter() {
    
        }
    
        static class Inner {
            public Inner() {
    
            }
        }
    }
    

内部类使用场景与作用

 为什么在Java中需要内部类?总结一下主要有以下四点:

  1. 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,

  2. 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

  3. 方便编写事件驱动程序

  4. 方便编写线程代码

参考

Java内部类详解