常用类之内部类

内部类

成员内部类

  1. 定义:内部类就是在类的内部定义另一个类

  2. 使用:

    • 内部类可以直接访问外部类的成员/方法,包括私有

      • 当内部类中没有和外部类同名的属性/方法时:可以直接使用
      • 当内部类中有和外部类同名的属性/方法时:外部类名.this.属性/方法
    • 外部类调用内部类方法,必须先创建对象

      • 内部类名 对象 = 内部类对象

      • 内部类 对象名 = new 内部类()

    • 别的类要访问内部类的成员,就必须创建对象

      • 外部类名.内部类名 对象名= 外部类对象.内部类对象
      • 外部类.内部类 对象名 = new 外部类对象().new.内部类对象()

      例子

package day1209;

public class Outer1 {
    int num = 20;

    String name = "Outer1";

    public void method(){
        System.out.println("这是外部类中的method方法");
    }
    public void show(){
        System.out.println("这是show方法");
    }

    public void outerMethod(){
        //外部类也可以使用内部类的属性和方法 --先创建内部类对象
        Inner inner = new Inner();
        System.out.println(inner.name);
        inner.showMethod();
    }

    //内部类 -- 直接写在类中 成员内部类
    //内部类同样可以使用四种访问权限修饰符来控制访问
    private class Inner{
        String name = "Inner";

        public void method(){
            System.out.println("这是内部类中的method方法");
        }

        public void method2(){
            System.out.println("内部类中的方法");
        }

        public int innerMe(){
            return 20;
        }
        public void showMethod(){
            System.out.println("这是内部类中的showMethod方法");
            //在内部类中可以直接使用外部类的方法和属性
            //1.当属性/方法不同名的时候,可以直接使用
            System.out.println(num);
            show();

            //2.当属性/方法重名的时候,需要强制指定使用外部类
            //外部类.this.属性/方法 -- 强制使用同名的外部类中的方法
            System.out.println("Outer1.this.name");
            Outer1.this.method();

            //3.当属性/方法重名的时候,直接使用的时候使用的是内部类中的属性和方法
            System.out.println(name);
            method();
            //Outer1.this.method();

            //内部类中可以直接调用自己的方法
            method2();
        }
    }

}

静态内部类

  1. 定义:使用static修饰的内部类

  2. 使用:

    • 外部类调用静态内部类的非静态方法

      • 外部类名.内部类名 对象名 = new 外部类名.内部类名();(或者内部类名 对象名 = new 内部类名())
    • 外部类调用静态内部类的静态方法

      • 内部类.静态内部类的静态方法
    • 内部类使用外部类的静态方法

      • 外部类.外部类的静态方法
    • 内部类使用外部类的非静态方法

      • 创建外部类对象:外部类 .对象名=new 外部类名()

      例子

package day1209;

public class Outer2 {
    public static void m1(){
        System.out.println("外部类的静态方法");
    }

    public void m2(){
        System.out.println("外部类的非静态方法");
    }

    public void outerMethod(){
        //外部类使用内部类的静态方法
        Inner.method();
        //外部类中使用内部类的非静态方法
        //先创建内部类对象,然后使用
        Outer2.Inner inner = new Outer2.Inner();//可以直接写 Inner inner = new Inner();
        inner.method2();

    }

    //如果内部类中存在静态成员--则这个内部类必须时static的
    //有静态方法的内部类必定是静态内部类
    static class Inner{

        public static void method(){
            System.out.println("静态内部类中的静态方法");
            //内部类使用外部类的静态方法
            Outer2.m1();
            //内部类使用外部类的非静态方法
            //先new出外部类对象
            Outer2 outer2=new Outer2();
            outer2.m2();
        }

        public  void method2(){
            System.out.println("内部类中的非静态方法");
        }
    }
}

局部内部类

  1. 定义:定在类中的方法中的内部类叫做局部内部类(用的很少)

  2. 使用

    • 局部内部类的作用范围仅限于本方法中

    • 局部内部类在访问他所在方法中的局部变量必须用final修饰

      • 局部内部类想要使用局部变量,那么,变量必须变成常量

      • 因为当调⽤这个⽅法时,局部变量如果没有⽤final修饰,他的⽣命周期和⽅法的⽣命周期是⼀样的,当⽅法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有⻢上消失想⽤这个局部变量,就没有了,如果⽤final修饰会在类加载的时候进⼊常量池,即使⽅法弹栈,常量池的常量还在,也可以继续使⽤

      • jdk 1.8 取消的这个定义 , 其实不是取消了, 是设置为了隐式的

    例子

    public class Otuer3 {
    
        public void method(){
            final String name = "我是你爸爸";
    
            //内部类在方法中--局部内部类
            class Inner{
                public void method(){
                    System.out.println("这是局部内部类的方法");
                }
                public void show(){
                    //局部内部类可以使用方法的变量
                    System.out.println(name);//局部内部类中使用的局部变量, 建议使用final显式修饰的方式
                }
            }
            //创建对象的方式使用
            Inner inner = new Inner();
            inner.method();
            inner.show();
        }
    }
    
    

匿名内部类

  1. 定义

    • 匿名内部类就是局部内部类的简写形式,相当于是⼀个没有名字的普通⼦类/实现类
    • 匿名内部类⽤于定义接⼝的或者类的⼦类
  2. 使用

    • 前提是必须存在一个类,或则接口
    • 这里的类可以是具体的类也可以是抽象类
    • 相当于是有⼀个没有名字的⼦类继承或者实现⼀个类或接⼝,然后重写⾥⾯的⽅法,本质是⼀个继承了该类或者实现了该接⼝的匿名⼦类对象
    • 多⽤于规则简单,⼦类使⽤很少的接⼝应⽤中
 public void method2(){
        class Inner implements A{
            @Override
            public void show() {
                System.out.println("我是A的实现类");
            }
        }
        A a = new Inner();
        A a2 = new Inner();
        a.show();
        a2.show();

        //匿名内部类 -- 替代局部内部类
        A a1 = new A() {
            @Override
            public void show() {
                System.out.println("这是一个匿名内部类");
            }
        };
        a1.show();

        //匿名内部类 --服务对象 任何类都可以使用匿名内部类的方式创建对象
        //匿名内部类就是局部内部类的简写形式
        //匿名内部类就相当于一个没有名字,没有单独书写的普通子类/实现类
        Normal normal = new Normal();
        normal.show();

        Normal n1 = new Normal(){
            @Override
            public void show() {
                System.out.println("匿名的子类,重写normal的show方法");
            }
        };
        n1.show();


    }

在外部使用外部类和内部类的方法/属性

public class OuterDemo {
    public static void main(String[] args) {
        //在外部使用成员内部类

        //1.使用外部类方法
        Outer1 outer1 = new Outer1();
        outer1.outerMethod();//new Outer1().outerMthod();
        new Outer1().outerMethod();

        //2.使用成员内部类对象 --当前成员内部类 可以被访问到 --非private修饰
        //创建内部类对象
        //第一种 --依次创建
       Outer1 o1 = new Outer1();
       Outer1.Inner inner = o1.new Inner();
       inner.method2();
        //第二种 -- 单纯创建内部类对象
       Outer1.Inner inner1=new Outer1().new Inner();//new Outer1().new Inner().method2();
       inner.method2();
       //成员方法 new 外部类名.方法名()
        // 内部类--看成是一个方法的话 new 类名().内部类
        //类 -- 创建对象--构造方法 new 内部类名()
        //new 外部类名().new 内部类名();

        int i = o1.userInnerMe();
        System.out.println(i);

        //使用静态内部类
        //1.使用静态内部类的非静态方法
        //先创建对象
        Outer2.Inner inner2 = new Outer2.Inner();
        inner2.method2();
        //使用静态内部类的静态方法
        Outer2.Inner.method();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值