Java基础 Day12

一、接口的新特性

1、JDK8 版本的接口新特性

(1)允许在接口中定义非抽象方法,但是需要使用关键字 default 修饰,这些方法就是默认方法

作用:解决接口升级的问题

接口中默认方法的定义格式:
格式:public default 返回值类型 方法名(参数列表) {}
示例:public default void show() {}

在实现类中调用接口的默认方法:
格式:接口名.super.方法名();

注意事项:

public可以省略,省略后仍是public权限,default不能省

实现类中可以重写默认方法,在实现类中需要去掉default关键字

若一个实现类实现了多个接口,多个接口有相同的默认方法,则实现类必须重写该默认方法

(2)允许在接口中定义静态方法

格式与类中的静态方法格式相同

注意事项:

public可以省略,static不能省略

接口中的静态方法只能通过接口名进行调用,不允许实现类通过对象进行调用

2、JDK9 版本的接口新特性

允许在接口中定义私有方法(可以是静态的)

便于接口中的非抽象方法进行调用

由于静态方法只能调用静态方法,所以私有方法可以是静态的

二、代码块

在Java类下,使用 { } 括起来的代码被称为代码块

1、局部代码块

位置:方法中定义

作用:限定变量的生命周期,及早释放,提高内存利用率

2、构造代码块

位置:类中方法外定义

特点:每次构造方法执行的时,都会执行该代码块中的代码,并且在构造方法执行前执行

作用:将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性

3、静态代码块

位置:类中方法外定义

特点:需要通过static关键字修饰,随着类的加载而加载,并且只执行一次

作用:在类加载的时候做一些数据初始化的操作

public class BlockDemo {
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student(1);
    }
}

class Student {

    static String school;

    static {  // 静态代码块
        school = "mySchool";
        System.out.println("静态代码块...");
    }

    {  // 构造代码块
        System.out.println("构造代码块...");
    }

    Student() {
        System.out.println("Student类的空参构造");
    }

    Student(int n) {
        System.out.println("Student类的带参构造");
    }
}

输出:
静态代码块...
构造代码块...
Student类的空参构造
构造代码块...
Student类的带参构造

三、内部类

1、成员内部类

内部类就是定义在一个类里面的类

内部类中,访问外部类成员:直接访问,包括私有(若有重名,用外部类名.this.成员)

外部类中,访问内部类成员:需要创建对象访问

格式:外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();

public class InnerDemo {
    public static void main(String[] args) {
        Outer.Inner obj1 = new Outer().new Inner();
        obj1.getN();
        //obj1.getM();  报错
        obj1.getOuterMember();
        obj1.getOuterN();

        Outer obj2 = new Outer();
        obj2.getInnerMember();
    }
}

class Outer {

    private int m = 1;
    private int n = 10;

    public void getM() {
        System.out.println("Outer getM: m = " + m);
    }

    public void getInnerMember() {
        System.out.println("Outer getInnerMember");
        Inner inner = new Inner();
        inner.getN();
    }

    class Inner {
        public int n = 2;

        public void getN() {
            System.out.println("Inner getN: n = " + n);
        }

        public void getOuterMember() {
            System.out.println("Inner getOuterMember");
            getM();
            m = 3;
            getM();
        }

        public void getOuterN() {
            System.out.println("Inner getOuterN Outer.n = " + Outer.this.n);
        }
    }
}

输出:
Inner getN: n = 2
Inner getOuterMember
Outer getM: m = 1
Outer getM: m = 3
Inner getOuterN Outer.n = 10
Outer getInnerMember
Inner getN: n = 2

2、静态内部类

有 static 修饰的成员内部类

格式:外部类名.内部类名 对象名 = new 外部类名.内部类对象();

范例:Outer.Inner in = new Outer.Inner();

注意:静态只能访问静态

在静态内部类中如果要访问外部类的非静态成员,需要创建外部类对象

3、局部内部类(不常用)

放在方法、代码块、构造器等执行体中的类

4、匿名内部类

概述:匿名内部类本质上是一个特殊的局部内部类(定义在方法内部)

前提:需要存在一个接口或类

格式:new 类名 / 接口名 () {}

new 类名表示继承这个类,new 接口名表示实现这个接口

匿名内部类可以使代码更加简洁,定义一个类的同时对其进行实例化

Tips:方法的形参是接口类型,应该传入这个接口的实现类对象

匿名内部类可以作为方法的实际参数进行传输

如果接口里的抽象方法较少,建议采用匿名内部类

如果接口里的抽象方法较多,建议传入实现类的对象

public class AnonClassDemo {
    public static void main(String[] args) {
        // 法一:采用匿名内部类
        useInter(new Inter() {
            @Override
            public void show() {
                System.out.println("匿名内部类");
            }
        });

        // 法二:传入实现类的对象
        Inter i = new InterImpl();
        // 或者 InterImpl i = new InterImpl();
        useInter(i);
    }

    public static void useInter(Inter i) {
        i.show();
    }
}

interface Inter {
    void show();
}

class InterImpl implements Inter {
    @Override
    public void show() {
        System.out.println("实现类");
    }
}

输出:
匿名内部类
实现类

四、Lambda表达式

1、简介

Lambda表达式是 JDK8 开始后的一种新语法形式。

作用:简化匿名内部类的代码写法

快捷键:将光标移动到匿名内部类处,按 alt + enter,可以直接化简成 Lambda 表达式

(匿名内部类被重写方法的形参列表) -> {
    被重写方法的方法体代码
}

useInter(() -> {
    System.out.println("Lambda表达式");
})       

Lambda 表达式只能简化函数式接口的匿名内部类的写法形式

函数式接口:接口中有且仅有一个抽象方法

通常在接口上加上一个 @FunctionalInterface 注解,标记该接口必须是满足函数式接口

2、Lambda表达式的省略写法

参数类型可以省略不写。

如果只有一个参数,参数类型可以省略,同时 () 也可以省略

如果Lambda表达式的方法体代码只有一行代码

可以省略大括号不写,同时要省略分号

此时,如果这行代码是return语句,必须省略return不写,同时也必须省略 ";" 不写

3、Lambda表达式和匿名内部类的区别

使用限制不同

匿名内部类 : 可以操作类, 接口

Lambda表达式 : 只能操作函数式接口

实现原理不同

匿名内部类:编译之后,产生一个单独的.class字节码文件

Lambda表达式:编译之后,没有一个单独的.class字节码文件

Tips:import java.util.* 表示导入 uitl 包里的所有的类(*是通配符)

五、窗体、组件、事件

1、窗体 JFrame

import javax.swing.*;

public class FrameDemo {
    public static void main(String[] args) {
        // 创建窗体对象
        JFrame frame = new JFrame();
        // 设置窗体标题
        frame.setTitle("Frame Demo");
        // 设置关闭模式,关闭窗体后停止Java程序
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置宽和高
        frame.setSize(500, 500);
        // 设置窗体可见,这一步放在最后
        frame.setVisible(true);
    }
}

2、组件

(1) JButton 按钮组件

添加组件:

窗体对象.setLayout(null); 取消默认布局

创建组件对象

组件对象.setBounds(x,y,width,height); 设置摆放位置

窗体对象.getContentPane().add(组件对象);

(2)JLabel 图片或文本组件

JLabel​(String text) 使用指定的文本创建一个 JLabel 对象

JLabel​(Icon image) 创建一个具有指定图像的 JLabel 对象

如果多个组件摆放在同一个位置,后添加的组件,会被压在底层

在写路径时,\ 要写成 \\

frame.setLayout(null);

JButton button = new JButton("Click Me");
button.setBounds(30, 30, 100, 30);
frame.add(button);

JLabel label = new JLabel("Hello World");
label.setBounds(30, 60, 100, 30);
frame.add(label);

JLabel png = new JLabel(new ImageIcon("D:\\..."));
png.setBounds(30, 90, 810, 875);
frame.add(png);

3、事件

ActionListener : 动作监听器  (鼠标点击, 空格按下)

KeyListener : 键盘监听器

焦点:程序的注意力集中在某一个组件上

一个按钮组件被创建后,焦点默认集中在按钮上

// 为按钮添加动作监听
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Clicked");
    }
});
// 取消按钮的焦点
button.setFocusable(false);
// 添加键盘监听
frame.addKeyListener(new KeyListener() {
    @Override
    public void keyTyped(KeyEvent e) {
        // 只能监听一部分按键
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("Key pressed: " + e.getKeyCode());
    }

    @Override
    public void keyReleased(KeyEvent e) {
        System.out.println("Key released: " + e.getKeyCode());
    }
});

六、设计模式

1、概念

一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性

2、两个常用的设计模式

(1)适配器设计模式:解决接口与接口实现类之间的矛盾

接口实现类可能不需要实现接口中的所有抽象方法

实现步骤:

编写一个 xxxAdapter 类,  实现对应接口

重写内部所有抽象方法,  但方法都是空实现

让自己的类去继承适配器类, 重写自己需要的方法即可

为了避免其他类创建适配器类的对象,  使用 abstract 进行修饰

(2)模板设计模式:把抽象类整体就可以看做成一个模板

把模板中不能决定的东西定义成抽象方法

让使用模板的类(继承抽象类的类)去重写抽象方法实现需求

模板已经定义了通用结构,使用者只需要关心自己需要实现的功能即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值