一文搞定内部类

概念

内部类,顾名思义就是定义在类内部的类。

特别之处:外部类可以访问内部类的所有元素【包括私有元素】

优点

  • 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据
  • 内部类不为同一包下的其他类所见,具有很好的封装性
  • 内部类有效实现类“多重继承”,优化java单继承的缺陷
  • 匿名内部类可以很方便的定义回调

应用场景

  • 适当使用内部类,使得代码更加灵活富有扩展性
  • 当某个类除了它的外部类,不在被其他的类所使用

分类

内部类可以分为:

  • 静态内部类:定义在类内部的静态类
  • 成员内部类:定义在类内部的非静态类
  • 匿名内部类:定义在类内部没有名字的内部类【日常开发中使用较多】
  • 局部内部类:定义在类内部的方法中的内部类

静态内部类

  •   创建方式: Outer.StaticInner = new Outer.StaticInner();
  •   变量:静态内部类中可以定义静态变量与实例变量
  •   方法:静态内部类中可以定义静态方法与实例方法
  •   访问外部类:静态内部类的只能访问外部类的静态元素【静态变量与静态方法】
/**
 * 静态内部类
 * 创建方式: Outer.StaticInner = new Outer.StaticInner();
 * 变量:静态内部类中可以定义静态变量与实例变量
 * 方法:静态内部类中可以定义静态方法与实例方法
 * 访问外部类:静态内部类的只能访问外部类的静态变量
 */
public class Outer {
    private static int i=1;
    private  int j=1;
    public static void go(){
    System.out.println("我是外部类的go方法,我直接访问了内部类的私有静态变量 age"+ 
         StaticInner.age);
    }

  static  class StaticInner{
        private static int age = 20;
        private String name="zhangsan";

       public static void run(){
           System.out.println("直接访问外部类的私有静态成员:"+i);
           Outer.go();  //访问静态方法
       }

       public void hello(){
           System.out.println("直接访问外部类的私有静态成员:"+i);
           go();         //访问静态方法
       }
    }
}

测试

public class Test {
    public static void main(String[] args) {
//        静态内部类测试
        Outer.StaticInner staticInner =new Outer.StaticInner();
        staticInner.run();
        staticInner.hello();
    }
}

结果

成员内部类

  •  创建方式: 外部类名.内部类名=nwe 外部类实例.内部类名();
  •  变量:成员内部类中只能定义实例变量,不能定义静态变量
  •  方法:成员内部类中只能定义实例方法,不能定义静态方法
  •  访问外部类:可以直接访问外部类的所有元素【静态元素,实例元素】
/**
 * 成员内部类
 * 创建方式: 外部类名.内部类名=nwe 外部类实例.内部类名();
 * 变量:成员内部类中只能定义实例变量,不能定义静态变量
 * 方法:成员内部类中只能定义实例方法,不能定义静态方法
 * 访问外部类:可以直接访问外部类的所有元素【静态元素,实例元素】
 */
public class Outer1 {
    private static int i=1;
    private  int j=1;
    public static void go(){
        System.out.println("我是外部类的静态方法");
    }
    public  void run(){
        System.out.println("我是外部类的实例方法");
    }

class Inner{
        private int age=20;

       public  void  hello(){
           System.out.println("访问外部类的静态变量:"+i);
           System.out.println("访问外部类的实例变量:"+j);
           go();
           run();
       }
    }
}

测试:

public class Test {
    public static void main(String[] args) {
//       成员内部类测试
        Outer1 outer1 = new Outer1();
        Outer1.Inner inner = outer1.new Inner();
        inner.hello();
    }
}

结果:

 匿名内部类


/**
 * 匿名内部类
 * 须知:匿名内部类必须继承一个抽象类或者实现一个接口
 * 变量:匿名内部类只能定义实例变量,不能定义静态变量
 * 方法:匿名内部类只能定义实例方法,不能定义静态方法
 */
public class Outer2 {
    public void test(){
     new Animal(){
         @Override
         public void run() {
             System.out.println("我是匿名内部类");
         }
     }.run();
    }


}
//定义一个抽象类用于匿名内部类继承
abstract class Animal{
    public abstract void run();
}

测试:

    public static void main(String[] args) {
        Outer2 outer2 = new Outer2();
        outer2.test();
    }

结果:

局部内部类

  • 创建方式:在对应方法内 new 内部类();
  • 定义在实例方法中的内部类可以访问外部类的所有变量和方法
  • 定义在静态方法中的内部类只能访问外部内的静态变量和方法
/**
 * 局部内部类
 * 创建方式:在对应方法内 new 内部类();
 * 定义在实例方法中的内部类可以访问外部类的所有变量和方法
 * 定义在静态方法中的内部类只能访问外部内的静态变量和方法
 */
public class Outer3 {
    private int age=20;
    private static String name="zhangsan";
    public void find(){
        System.out.println("我是外部类的实例方法");
    }

    public static void found(){
        System.out.println("我是外部类的静态方法");
    }


    public  void test(){
//        定义在实例方法中的内部类
          class Inner{
             private String  address="岳阳";
             public void run(){
                 System.out.println("我是局部内部类的run方法");
                 System.out.println("访问外部内的实例变量"+age);
                 System.out.println("访问外部内的静态变量"+name);
                 find();
                 Outer3.found();
             }
         }
        Inner inner = new Inner();
        inner.run();
    }


    public  static void testStatic(){
//        定义在静态方法中的内部类
        class InnerStatic{
            private String  address="岳阳";
            public void run(){
                System.out.println("我是局部内部类的run方法");
//                System.out.println("访问外部内的实例变量"+age);  不能访问外部类的实例变量
                System.out.println("访问外部内的静态变量"+name);
//               find();    不能访问外部类的实例方法
                Outer3.found();
            }
        }
        InnerStatic inner = new InnerStatic();
        inner.run();
    }

}

测试

    public static void main(String[] args) {
        Outer3 outer3 = new Outer3();
        outer3.test();

        Outer3.testStatic();
    }

结果

 

总结【个人理解】

  • 静态内部类是所属于类的范围的,所以可以定义静态元素【静态变量以及静态方法】,其他非静态的内部类是所属于对象的,所以不能定义静态元素,只能定义实例变量与实例方法。
  • 静态的可以访问父类静态的,因为类加载的时候实例还没被创建
  • 实例的既可以访问父类静态的,也可以访问父类实例的,因为创建实例一定是在类加载后,也就是静态元素已经全部加载完成后,所以可以访问静态元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值