内部类

内部类

一、基本概念

  • 基本介绍:

    一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员(五大成员:属性、方法、构造器、代码块、内部类),内部类最大特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。

  • 基本语法

    class Outer{//外部类
        class Inner{//内部类
            
        }
    }
    class Other{//外部其他类
        
    }
    
  • 内部类的分类

    • 定义在外部类局部位置上(比如方法内/代码块)
      1. 局部内部类(有类名)
      2. 匿名内部类(无类名,重点!!!!
    • 定义在外部类的成员位置上:
      1. 成员内部类(没用static修饰)
      2. 静态内部类(使用static修饰)

二、局部内部类的使用

说明:局部内部类是定义在外部类的局部位置,比如方法中,并且有类名,也可以在代码块中,本质仍然是个类。

  1. 可以直接访问外部类的所有成员,包括私有的;
  2. 不能添加访问修饰符,因为他的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final 修饰,因为局部变量也可以使用final;
  3. 作用域:仅仅在定义它的方法或代码块中;
  4. 局部内部类 访问 外部类的成员【访问方式:直接访问】;
  5. 外部类 访问 局部内部类的成员【访问方式:创建对象,再访问(注意:必须在作用域内)】;
  6. 外部其他类,不能访问局部类(因为局部类地位是一个局部变量);
  7. 如果外部类和局部内部类的成员重名时,默认遵守就近原则,如果想访问外部类的成员,使用(外部类名.this.成员)去访问,(外部类名.this)本质就是外部类的对象;

tip:内部类是延时加载的,也就是说只会在第一次使用时加载。不使用就不加载,所以可以很好的实现单例模式。

三、匿名内部类的使用

  1. 要点

    1. 本质是类
    2. 内部类
    3. 该类没有名字,类名由系统分配
  2. 匿名内部类的基本语法

new 类或接口(参数列表){
	//类体
};
  1. 匿名内部类使用细节
    1. 匿名内部类的语法比较奇特,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面代码分析可以看出这个特点,因此可以调用匿名内部类方法。

      匿名内部类的方法调用1

      匿名内部类的方法调用2

    2. 可以直接访问外部类的所有成员,包含私有的

    3. 不能添加访问修饰符,因为它的地位就是一个局部变量。

    4. 作用域:仅仅在定义它的方法或者代码块中。

    5. 匿名内部类 ----访问----->外部类成员【访问方式:直接访问】

    6. 外部其他类---不能访问---->匿名内部类(因为 匿名内部类地位是一个局部变量)

    7. 如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵守就近原则,如果相访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

    8. 匿名内部类使用一次就不能再使用,会被立马销毁,但是创建的对象还能使用。

    9. 匿名内部类的构造方法:因为匿名内部类没有名字这个特殊性质,所以我们无从给它指定构造方法,构造方法必须和类名同名,类名都没有,构造方法就无从谈起了。但是匿名内部类可以通过直接调用父类的构造方法实现初始化,当然要求父类构造方法对它父类中定义的成员变量进行初始化。

四、 成员内部类的使用

说明:成内部类是定义在外部类的成员位置,并且没有static修饰。

  1. 可以直接访问外部类的所有成员,包含私有的。

    class Outer01{//外部类
    	private int n1 = 10;
        public String name = "张三";
        
        class Inner01{
            public void say(){
                System.out.println("Outer01 的 n1 = " + n1 + "Outer01 的 name = " + name);
            }
        }
    }
    
  2. 可以添加任意的访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。

  3. 作用域:和外部类的其他成员一样,为整个类体。

  4. 成员内部类 --- 访问----> 外部类的成员(比如属性)【访问方式:直接访问,外部类名.this.成员当然也可以】。

  5. 外部类 ---访问---->内部类【访问方式:创建对象,再访问】。

  6. 外部其他类---访问---->成员内部类。

  7. 如果外部类和内部类的成员重名时,内部类访问的话,默认遵守就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

五、静态内部类的使用

说明:静态内部类是定义在外部类的成员位置,并且有static修饰。

  1. 可以直接访问外部类的所有静态成员,包含私有的但不能直接访问非静态成员。

  2. 可以添加任意访问修饰符,因为他的地位就是个成员。

  3. 作用域:同其他的成员,为整个类体。

  4. 静态内部类---访问----> 外部类(比如:静态属性)【访问方式:直接访问所有静态成员】。

    class Outer10{
        private int n1 = 10;
        private static String name = "张三";
    
         public static class Inner10{
            public void say(){
                System.out.println(name);
            }
        }
    }
    
  5. 外部类-----访问----->静态内部类 访问方式:创建对象,再访问

    class Outer10{
        private int n1 = 10;
        private static String name = "张三";
    
         public static class Inner10{
            public void say(){
                System.out.println(name);
            }
        }
    public void m1(){
            Inner10 inner10 = new Inner10();
            inner10.say();
        }
    }
    
  6. 外部其他类----访问----->静态内部类

    public class StaticInnerClass01 {
        public static void main(String[] args) {
    
            //外部其他类 使用静态内部类
            //方式1
            //因为静态内部类,是可以通过类名直接访问(前提是满足访问权限)
            Outer10.Inner10 inner10 = new Outer10.Inner10();
            inner10.say();
            System.out.println("=============");
            //方式2
            //编写一个方法,可以返回静态内部类的实例
            Outer10.Inner10 inner101 = outer10.getInner10();
            inner101.say();
            //编写静态一个方法,可以返回静态内部类的实例
            System.out.println("**************");
            Outer10.Inner10 inner10_ =  Outer10 .getInner10_();
            inner10_.say();
        }
    }
    
    
    class Outer10{
        private int n1 = 10;
        private static String name = "张三";
         public static class Inner10{
            public void say(){
                System.out.println(name);
            }
        }
        public void m1(){
            Inner10 inner10 = new Inner10();
            inner10.say();
        }
    
        public  Inner10 getInner10(){
             return new Inner10();
        }
    
        public static Inner10 getInner10_(){
            return new Inner10();
        }
    }
    
  7. 如果外部类和静态内部类的成员重名时,静态内部类访问时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问。

tip: 如果一个类要被声明为static的,只有一种情况,就是静态内部类。

posted @ 2022-12-18 15:48  凉白茶  阅读(163)  评论(0编辑  收藏  举报