Java进阶(第三期)
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
文章目录
- Java基础(第三期)
- 一、接口新特性
- 1.1 JDK8版本
- 1.2 JDK9版本
- 代码块
- 二、内部类
- 1、成员内部类
- 1.2 内部类成员访问
- 2、 静态内部类
- 3、 局部类
- 4、匿名内部类(重要)
- 三 Lambda表达式
- 3.1 简单概述
- 3.2 Lambda表达式简写规则
- 3.3 Lambda和匿名类的区别i
JDK8 版本接口特性:
1. 允许定义非抽象方法,但是需要加入 default 关键字 (重写方法的时候不需要)
- 做用:解决接口的升级问题
- 注意事项:
1. public 可以省略,但是default 不能省略
2. 默认方法:实现类是允许重写的,但是需要去掉default关键字
3. 如果实现了多个接口,多个接口中存在相同的默认方法,实现类必须重写默认方法
代码示例:
package com.liujintao.jdk8;
public class InterfaceTest {
/*
允许在接口中定义新的抽象方法:
需要在接口中对添加的方法加上 default 关键字
*/
public static void main(String[] LiuJInTao) {
Realize r = new Realize();
r.print(); // is---print
r.show(); // is---show
r.method(); // is---method
r.handle(); // is---default---eat
r.eat(); // is---eat
}
}
// 定义一个接口
interface Inter {
public void show();
public void print();
// 在接口中添加新的抽象方法(还能带有逻辑)
public default void method() {
System.out.println("is---method");
};
}
interface A {
public void eat();
// 接口中继续添加新的抽象方法,使用 default 修饰
public default void handle () {
System.out.println("is---handle");
}
}
/**
* 下面是实现类(多继承重写抽象方法,以及新增默认的抽象方法)
*/
// 定义第一个实现类;实现接口,并且重写里面的方法
class Realize implements Inter , A {
@Override
public void show() {
System.out.println("is---show");
}
@Override
public void print() {
System.out.println("is---print");
}
// 重写default默认添加的抽象方法
@Override
public void method() {
Inter.super.method();
System.out.println("is---method");
}
// 重写A接口里面的抽象方法和默认新增方法
public void eat () {
System.out.println("is---eat");
}
public void handle () {
System.out.println("is---default---eat");
}
}
2. 允许定义静态方法
- 理解:既然接口已经允许方法调用了,干脆也方法静态方法,可以使用类名调用
- 注意事项:
1. public 可以省略,但是 static 不能省略
2. 接口中的静态方法,只允许接口名进行调用,不允许实现类调用
// 定义一个接口
interface A {
public void eat();
// 接口中继续添加新的抽象方法,使用 default 修饰
public default void handle () {
System.out.println("is---handle");
}
// 这是一个接口中的静态方法 (可以省略 public)
public static void function () {
System.out.println("is---A---static---function");
}
}
// 调用接口
// 调用静态方法(接口名.方法名)调用
A.function();
package com.liujintao.jdk9;
public class InterfaceDemo {
}
/**
* 定义一个接口
*/
interface Inter {
void show();
void pritn();
default void start () {
System.out.println("开始");
log();
}
default void end () {
System.out.println("结束");
log();
}
// 将重复的代码抽取出来,并私有化 (私有化不能写default)
private void log() {
System.out.println("记录一次");
}
}
内部类:再类中定义的类
创建内部类引用的格式:
外部类名.内部类名 对象名 = new 外部类名().new内部类名();
成员访问的细节:
1. 内部类中,访问外部类成员: 直接访问,包括私有。
2. 外部类中,访问内部类成员: 需要创建对象访问。
package com.liujintao.inner;
public class InnerDemo {
public static void main(String[] args) {
// 创建内部类对象访问内部类中的成员:
Inner.Inner2 i = new Inner.Inner2();
System.out.println("user:" + i.user + "---" + "age:" + i.age); // 访问内部类的成员(如果是private就得使用set和get)
i.method(); // 内部类的静态方法直接类名访问;
}
}
// 外部类
class Inner {
private String name = "张三";
private char gender = '男';
// 内部类
class Inner2 {
private String name = "李四";
public String user = "admin";
public int age = 18;
public void method() {
System.out.println("我是内部类的静态方法");
}
}
}
user:admin—age:18
我是内部类的静态方法
下面练习加深印象:
class1.class2 s = new class1().new class2();
s.shou();
class class1 {
int num = 10;
class class2 {
int num = 20;
public void shou () {
int num = 30;
System.out.println(num); // 30
System.out.println(this.num); // 20
System.out.println(class1.this.num); // 10
}
}
}
注意:在成员内部中访问所在外部类对象,需要使用: 外部类名.this
静态内部类: static 修饰的成员内部类
创建对象格式: 外部类名.内部类名 对象名 = new 外部类名(). new 内部类名()
注意事项:静态方法智能访问静态方法(因为静态会随着类的加载而加载)
package com.liujintao.inner;
import java.sql.SQLOutput;
public class InnerDemo2 {
public static void main(String[] LiuJinTao) {
// 访问静态的,直接类名调用即可!
Wai.Nei.show();
}
}
class Wai {
int num = 10;
static int num2 = 20;
// 静态内部类
static class Nei {
public static void show() {
System.out.println("show------");
Wai w = new Wai();
System.out.println(w.num); // 10
System.out.println(num2); // 20
}
}
}
show------
10
20
package com.liujintao.inner;
import java.sql.SQLOutput;
public class InnerDemo3 {
/*
局部内部类: 放在方法、代码块、构造器等执行体中
*/
public static void main(String [] LiuJinTao) {
// 使用局部类
Wai1 w = new Wai1();
w.show(); // 里面的逻辑执行,自然访问到了method方法
}
}
class Wai1 {
public void show () {
// 局部内部类
class Nei1 {
public void method() {
System.out.println("method-----");
}
}
Nei1 n = new Nei1();
n.method();
}
}
method-----
匿名内部类:
匿名内部类本质是一个特殊的局部内部类(定义在方法内部)
前提条件:
new 类名\ 接口名 () {}
new 类名 () {} : 代表继承这个类
new 接口名 () {} : 代表实现这个接口
+ 问题:方法的形参是接口类型,我们该传入的是什么?
+ 回答:传入的是该接口的实现类对象
+ 多态的实现条件
接口引用需要实现类对象
父类引用需要子类对象
package com.liujintao.inner;
public class InnerDemo4 {
public static void main(String[] LiuJinTao) {
// 调用静态方法,参数需要一个接口对象(也就是实现类对象)
method(new Inter() {
// 实现类必须重写,要么编程抽象类
@Override
public void show() {
System.out.println("我是实现类");
}
});
}
// 静态类(参数需要实现类对象) 也就是说:接口引用需要实现类对象
public static void method(Inter i) {
i.show(); // 我是实现类
}
}
// 定义一个接口
interface Inter {
public void show();
}
package com.liujintao.lambda;
public class LambdaDemo {
public static void main(String [] LiuJinTao) {
// 匿名类实现 (传入一个实现类对象)
userInter(new Inter () {
@Override
public void show() {
System.out.println("我是匿名类传参");
}
});
// 使用Lambda表达式 实现传参
userInter( () -> {
System.out.println("我是Lambda表达式传参");
});
}
// 定义一个静态方法
public static void userInter (Inter i) {
i.show();
}
}
// 定义一个接口
interface Inter {
void show();
}
我是匿名类传参
我是Lambda表达式传参
package com.liujintao.lambda;
public class LambdaDemo2 {
public static void main(String[] LiuJinTao) {
userInters(new Inters () {
@Override
public int getSum(int a, int b) {
return a + b;
}
});
System.out.println("------------lambda表达式实现----------");
userInters((a, b) -> a + b);
}
// 定义一个静态方法(参数为一个接口引用,需要传入一个实现类对象)
public static void userInters (Inters sum) {
int result = sum.getSum(10, 20); // 调用实现类中重写的方法
System.out.println(result);
}
}
// 定义一个接口
interface Inters {
// 定义抽象方法的形参
int getSum(int a, int b);
}
30
------------lambda表达式实现----------
30