JAVA基础语法 day08

一、类中的成分:代码块

代码块是类的五大成分之一:成员变量,构造器,方法,代码块,内部类

1.1静态代码块

格式: static { }

特点:静态代码块由类本身持有,由于类只会加载一次,所以静态代码块也只会被执行一次

并且,静态代码块是优先执行的。比如下面代码,main方法在后面执行

作用:完成类的初始化,对静态变量进行初始化赋值

java 复制代码
//认识静态代码块
public class CodeDemo1 {
    //静态代码块,由static修饰,属于类,与类一起优先加载,执行一次
    public static String name;
    //作用,对类的资源初始化
    static{
        System.out.println("静态代码执行力");
        name = "张三";

    }
    public static void main(String[] args) {
        System.out.println("main 方法执行了");
    }
}

1.2实例代码块(构造代码块)

格式:{ }

特点:属于对象,每次创建对象时,执行实例代码块,并在构造器前执行

二、类中的成分:内部类

如果一个类定义在另一个类的内部,就称为内部类

场景:当一个类的内部有另一个完整的事务,且这个事务没有必要单独设计,就把他设计成内部类

2.1成员内部类

成员内部类就是类中的一个普通成员,类似之前学过的成员方法,成员变量。

特点:属于外部类的对象持有,因此不加static修饰!!

创建方法:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称()

java 复制代码
public class outer {
    //成员内部类,属于外部类对象,不能加static
    //创建方法:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称()
    public class inner {
        public static void main(String[] args) {
        }
        /*内部类的特点:
        1.可以直接访问外部类的静态成员(静态变量,静态方法)
        2.可以直接访问外部类的实例成员
        3.成员内部类的实例方法,可以直接拿到当前寄生的外部类对象: 外部类名.this
         */
    }
}
java 复制代码
public class demo1 {
    public static void main(String[] args) {
        outer.inner oi = new outer().new inner();
    }
}

2.2静态内部类

由static修饰的内部类,属于外部类本身持有,由于外部类只会加载一次,它也只加载一次

语法: 外部类名.内部类名 对象名 = new 外部类.内部类();

java 复制代码
//认识静态内部类
public class demo {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer.Inner(); //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
        //静态类可以访问外部类的静态成员吗? 可以
        //静态内部类中是否可以直接访问外部类的实例成员? 不可以!
        System.out.println(Outer.SchoolName);
        System.out.println(age); //报错
    }
}

2.3局部内部类(了解)

定义在方法,构造器里的类,没啥用

三、匿名内部类(重要)

3.1认识匿名内部类

1.匿名内部类,是一种特殊的局部内部类

2.所谓匿名,是因为不需要为这个类声明名字,它默认有个隐藏的名字

格式:虽然没有class关键字,但它就是一个类!!

java 复制代码
new 类或接口名(参数值){
    类体(一般是方法重写);

};这个分号不能忘掉!!

特点:匿名内部类,本质上就是一个子类,并且会立即创建出一个子类对象

java 复制代码
//认识匿名内部类及基础作用
public class test {
    public static void main(String[] args) {
        /*
        传统写法如下,定义一个新的类,继承animal,调用cat的cry方法。
        Animal a = new cat();
        a.cry();

         */

        //匿名内部类的写法:直接new animal,但是animal是抽象类,不能直接new
        //因此使用匿名内部类来new,new完之后需要立即重写cry方法
        Animal b = new Animal() {
            @Override
            public void cry() {
                System.out.println("猫 喵喵叫");
            }
        }; // new后面这一坨,就是匿名内部类,它就是animal的子类 ,注意这里需要分号
        b.cry();
    }
}

/*
class cat extends Animal{
    @Override
    public void cry(){
        System.out.println("cat 喵喵");
    }
}

 */

匿名内部类的作用:更方便的创建子类对象

3.2匿名内部类常见使用形式

通常作为一个对象参数传给方法。

需求:学生,老师参加游泳比赛

java 复制代码
//认识匿名内部类的使用形式:可作为对象参数传输给方法使用
//需求:学生,老师参加游泳比赛
public class test2 {
    static swim teacher = new swim(){
        @Override
        public void swimming(){
            System.out.println("老师正在自由泳");
        }
    };


    public static void main(String[] args) {
        Start(teacher);
        Start(new swim() {
            @Override
            public void swimming() {
                System.out.println("学生正在蛙泳");
            }
        }); //内部类对象直接作为参数写进去,跟上面是等价的
        }
        
    //设计一个方法,可以接收老师,学生参加比赛
    public static void Start(swim s) {
        System.out.println("比赛开始");
        s.swimming();
        System.out.println("比赛结束");
    }
    }


interface swim {
    public void swimming();//游泳方法
}

使用场景:

调用别人写好的方法实现需求时,传入一个匿名内部类对象给其使用。

例子:使用Comparator接口的匿名内部类对数组进行排序

java 复制代码
//完成数组的排序,理解匿名内部类在这里的用法
public class test3 {
    public static void main(String[] args) {
        Student[] Students = new Student[4];
        Students[0] = new Student("张三",18,175.4,'男');
        Students[1] = new Student("李四",20,169.5,'女');
        Students[2] = new Student("王五",16,183.0,'男');
        Students[3] = new Student("张麻子",35,171.3,'男');


            //需求,对数组按年龄大小排序
        //public static <T> void sort(T[] a, Comparator<? super T> c)
        //参数1:需要排序的数组
        //参数2:给sort方法声明比较器Comparator对象,指定排序规则
        //Comparator是一个接口,我们用匿名内部类来做

        //sort 方法会调用匿名内部类的compare方法,对数组中的元素进行比较
        Arrays.sort(Students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //指定排序规则
                //如果你认为左边对象 大于 右边对象,返回正整数
                //如果你认为左边对象 小于 右边对象 , 返回负整数
                //相等,返回 0
                if(o1.getAge()>o2.getAge()){
                    return 1;
                }else if(o1.getAge()<o2.getAge()){
                    return -1;
                }
                return 0;
                //上面这一大段也可以写成 return o1.getAge - o2.getAge 按照年龄升序
                //return o2.getAge - o1.getAge  按照年龄降序
            }
        });

        for (Student s : Students) {
            System.out.println(s);
        }
        }


    }
相关推荐
什么想法都无12 分钟前
stream
java·java stream
m0_7482336413 分钟前
WebService简介
java
Murphy202313 分钟前
.net4.0 调用API(form-data)上传文件及传参
开发语言·c#·api·httpwebrequest·form-data·uploadfile·multipart/form-
love静思冥想13 分钟前
Stream `Collectors.toList()` 和 `Stream.toList()` 的区别(Java)
java·stream
我曾经是个程序员23 分钟前
C#Directory类文件夹基本操作大全
服务器·开发语言·c#
白云~️25 分钟前
uniappX 移动端单行/多行文字隐藏显示省略号
开发语言·前端·javascript
编码浪子30 分钟前
构建一个rust生产应用读书笔记7-确认邮件2
开发语言·后端·rust
Ch.yang32 分钟前
【Spring】 Bean 注入 HttpServletRequest 能保证线程安全的原理
java·spring·代理模式
web1508509664134 分钟前
基于Mysql、JavaScript、PHP、ajax开发的MBTI性格测试网站(前端+后端)
java
昙鱼41 分钟前
springboot创建web项目
java·前端·spring boot·后端·spring·maven