java 内部类

内部类

1. 代码块

概述: 使用{}包裹起来的代码就是代码块
局部代码块

  • 位置:定义在方法中
  • 作用:限定变量的生命周期,让变量说占用的内存及早释放,提高内存的利用率
public class MethodCodeBlockDemo {

    public static void main(String[] args) {

        int a = 10;//如果不加代码块,此时变量a,是定义在方法当中,在整个main方法中都是有效的.
        System.out.println(a);

        //独立存在的大括号就是代码块.
        {
           int b = 10;
           System.out.println(b);
        }

        //System.out.println(b);//报错了
    }
}

构造代码块

  • 位置:类中方法外
  • 特点:每一次构造方法执行的时候都需要执行该代码块,并且优先于构造方法执行
  • 作用:可以将多个构造方法中的公共代码抽出到构造代码块中,以提高代码的复用性
public class Student {
    
    private String name;
    private int age;

    //1.位置:方法外,类里面.
    //2.执行时机:优先于构造方法运行的.每一次创建对象的时候,都会先运行构造代码块,然后再执行构造方法
    //3.作用:抽取构造方法中重复的代码.
    {
        System.out.println("开始执行构造方法了");
    }

    public Student() {
        
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    ...
}

静态代码块

  • 位置:类中方法外,并且需要用static进行修饰
  • 特点:随着类的加载而执行,并且只执行一次
  • 作用:进行系统的初始化的工作

代码块的执行顺序:先执行静态代码块,构造代码块,构造方法

2. 内部类

2.1概述及特点

  • 概述:就是把某一个类定义到另一个类里面
  • 特点:
    1. 内部类可以直接访问外部类的成员,包含私有的
    2. 外部类想要访问内部类的成员,就必须创建对象
public class Outer1 {

    String OuterName;
    private int OuterAge;

    public void OuterMethod(){
        //外部类要访问内部类的成员,直接访问是报错的,需要创建内部类的对象
        //System.out.println(InnerName);
        //System.out.println(InnerAge);
        Inner1 inner1 = new Inner1();
        System.out.println(inner1.InnerName);
        inner1.InnerMethod();
    }

    // 内部类
    public class Inner1{
        String InnerName;
        private int InnerAge;

        public void InnerMethod(){
            System.out.println(OuterName);
            System.out.println(OuterAge);
        }
    }

    public static void main(String[] args) {
        Outer1 outer1 = new Outer1() ;
        outer1.OuterMethod();
    }

}

2.2成员内部类

内部类按照定义的位置不同,可以分为两种:

  1. 成员内部类:把这个内部类定义在外部类的成员位置
  2. 局部内部类:把这个内部类定义在方法中

成员内部类常见的修饰符

  • public
    • 其他类创建内部类的对象格式:外部类名.内部类名 对象名 = new 外部类对象.内部类对象;
    Outer.Inner oi = new Outer().new Inner();
    
  • private
    • 其他类不能直接访问,只能在外部类中创建该类对象进行访问
  • static
    • 其他类创建内部对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();

2.3 局部内部类

局部内部类:把这个内部类定义在方法中
特点:

  1. 其他类无法直接访问局部内部类,局部内部类只能定义在该类的方法中进行访问
  2. 局部内部类是可以访问外部类的成员的,也可以访问方法中的局部变量
public class Outer3 {

    String OuterName;

    // 定义了一个方法outerMethod
    public void outerMethod(){

        // 局部变量
        int number = 10;

        // 局部内部类
        class Inner3{
            public void innerMethod(){
                System.out.println(OuterName);
                System.out.println(number);
                System.out.println("局部内部类的方法运行了");
            }
        }

        // 创建Inner3这个局部内部类的对象
        Inner3 inner3 = new Inner3();
        inner3.innerMethod();
    }
}

2.4 匿名内部类

匿名内部类:是一种特殊的内部类
前提:必须先定义一个类或者接口

new 类名/接口名() {
    
    // 重写方法
    
};
// 接口
public interface Inter {
    
    public abstract void show() ;
}

new Inter() {		// 本质上是一个实现了Inter这个接口的子类对象
   public void show() {
       System.out.println("Inter...show......") ;
   }
};

// 类
public class Student {
    public void show() {
    	 System.out.println("Student...show......") ;
    }
}

new Student() {  // 本质上是一个继承了Student这个类的子类对象
    public void show() {
    	 System.out.println("Student...show......") ;
    }
};

本质:实现某一接口或者继承某一类的子类
使用场景:把匿名内部类作为方法参数进行传递

public class AnonymityClassDemo {
    public static void main(String[] args) {

       //匿名内部类
        new Inter(){

            @Override
            public void show() {
                System.out.println("匿名内部类");
            }

        };

        //需求:调用goSwimming方法
        //创建实现类的对象
        //SwimmingImpl swimming = new SwimmingImpl();
        //调用方法
        //goSwimming(swimming);

        new Swimming() {
            @Override
            public void swim() {
                System.out.println("匿名内部类方式----去游泳了");
            }
        }.swim();

        System.out.println("------------------------------");

        // 多态
        Swimming swimming = new Swimming() {
            @Override
            public void swim() {
                System.out.println("匿名内部类方式----去游泳了");
            }
        };
        swimming.swim();

        System.out.println("------------------------------");

        //就可以用匿名内部类去改进
        goSwimming(
            new Swimming() {
                @Override
                public void swim() {
                    System.out.println("匿名内部类方式----去游泳了");
                }
            }
        );

    }

    public static void goSwimming(Swimming swimming){
        swimming.swim();
    }

}

3. lambda表达式

3.1 lambda

lambda表达式是jdk1.8以后提供的新的语法规则
lambda表达式体现的是另一种编程思想:函数式编程
函数:在数学中函数表示有输入量,输出量的一种计算方案,强调的是做什么.
java语言是面向对象的语言,面向对象的语言关注的是对象,谁可以帮我做什么事情

  • 面向对象的编程思想的代码体现
goSwimming(
    new Swimming() {
        @Override
        public void swim() {
            System.out.println("匿名内部类方式----去游泳了");
        }
    }
);
  • 函数式编程思想的代码体现
//lambda表达式方式
goSwimming(()->{
    System.out.println("lambda方式---去游泳了");
});

3.2 格式

(参数类型 参数名称) -> { 方法体代码 }

组成部分
使用lambda表达式的前提:必须有一个接口,并且这个接口中只有一个抽象方法(函数式接口)

3.4 省略格式

lambda表达式在使用的时候,也存在省略格式.

  1. 参数类型 可以省略,但是有多个参数的时候,不能只省略一个
  2. 如果参数有且只有一个时,可以省略小括号
  3. 如果 方法体代码只有一条,可以省略大括号和分号,甚至是return

3.5 注意事项

  • 使用lambda表达式必须有接口,并且要求接口中除了Object类的方法抽象表示形式以外,有且仅有一个抽象方法
  • 必须有上下文环境,才能推导出lambda对应接口

lambda表达式和匿名内部类的区别

  1. 使用前提
    • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体的类
    • lambda表达式:只能是接口,接口中有且仅有一个抽象方法
  2. 运行原理
    • 匿名内部类:编译后,产生一个独立的.class文件
    • lambda表达式:编译后,没有单独的.class文件,对应的字节码文件会在运行时动态生成
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aming_sth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值