java面向对象进阶进阶篇--《JDK8,JDK9接口中新增的方法、接口的应用、适配器设计模式》

个人主页→VON

收录专栏→java从入门到起飞

接口→接口和接口与抽象类综合案例

 

一、JDK8接口中新增的方法

在JDK 8中,接口新增了几个重要的特性和方法,其中最显著的是默认方法(Default Methods)和静态方法(Static Methods)。这些特性使得接口在Java编程语言中变得更加灵活和功能强大。

默认方法(Default Methods):

默认方法允许在接口中定义具体的方法实现,而不再是纯粹的抽象方法集合。主要特点包括:

  • 实现方法:接口可以包含带有默认实现的方法体
  • 兼容性:默认方法的引入不会破坏现有的接口实现,因为现有实现不需要强制重写新增的默认方法。
  • 多继承冲突解决:如果一个类实现了多个接口,并且这些接口具有相同的默认方法,编译器会要求显式重写冲突的方法,以明确指定使用哪个接口的方法

注意事项:

1. 默认方法不是抽象方法,所以不强制重写,但是重写时别忘了去掉default关键字。

 示例:
InterA接口
package com.von.day15b;

public interface InterA {
    public default void showA(){
        System.out.println("showA");
    }
}
InterImpl类
package com.von.day15b;

public class InterImpl implements InterA{
    @Override
    public void showA() {
        System.out.println("重写showA");
    }
}
结果展示: 

2. 定义默认方法时default不能省略。

3. 如果实现多个接口,并且多个接口中有相同的名字,子类就必须对该方法重写。 

示例: 
InterA
package com.von.day15b;

public interface InterA {
    public default void showA(){
        System.out.println("A接口中的showA");
    }
}
InterB
package com.von.day15b;

public interface InterB {
    public default void showA()
    {
        System.out.println("B接口中的showA");
    }
    public default void showB()
    {
        System.out.println("showB");
    }
}
InterImpl
package com.von.day15b;

public class InterImpl implements InterA,InterB{

}
结果展示:

静态方法(Static Methods):

接口中还可以定义静态方法,这些方法可以直接通过接口名调用,不需要实现类的实例。

接口中其他新增方法:

除了默认方法和静态方法,JDK 8中还新增了一些其他方法,以增强接口的功能:

  • 函数式接口(Functional Interface):引入了 @FunctionalInterface 注解,用于标识函数式接口,即只包含一个抽象方法的接口。

  • 接口中的方法可以有方法体:除了默认方法和静态方法外,还可以在接口中直接定义方法体的普通方法。

  • 接口中方法的可访问性:接口中的方法可以是 publicdefault 访问级别,不允许使用 privateprotected 访问级别。

 示例:

@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);

    default void log() {
        System.out.println("MathOperation interface");
    }

    static void info() {
        System.out.println("Static method in MathOperation interface");
    }
}

public class Main {
    public static void main(String[] args) {
        MathOperation addition = (a, b) -> a + b;
        MathOperation subtraction = (a, b) -> a - b;

        System.out.println(addition.operate(10, 5)); // 输出 15
        System.out.println(subtraction.operate(10, 5)); // 输出 5

        addition.log(); // 输出 "MathOperation interface"
        MathOperation.info(); // 输出 "Static method in MathOperation interface"
    }
}

在这个示例中,MathOperation 接口定义了一个抽象方法 operate,一个默认方法 log,和一个静态方法 infoMain 类实现了函数式接口,并展示了如何使用接口的不同方法。 

二、JDK9接口中新增的方法

JDK 9 在接口方面的改进相对于 JDK 8 并不多,但是在整体 Java 平台和语言的功能上有一些显著的变化和新增特性。

私有方法(Private Methods)

JDK 9 允许接口中定义私有方法,这些方法只能在接口内部使用,对实现类和其他类不可见。这使得接口能够更好地组织和重用代码逻辑。

interface MyInterface {
    default void publicMethod() {
        // 可调用私有方法
        privateMethod();
    }

    private void privateMethod() {
        // 接口内部私有方法的实现
    }
}

接口中的静态私有方法(Static Private Methods)

除了实例私有方法,JDK 9 还引入了接口中的静态私有方法,这些方法可以在接口的静态方法和默认方法中重复使用。

interface MyInterface {
    static void staticMethod() {
        // 可调用静态私有方法
        staticPrivateMethod();
    }

    private static void staticPrivateMethod() {
        // 接口内部静态私有方法的实现
    }
}

兼容性注解(@Deprecated, @DeprecatedSince)

JDK 9 引入了两个新的注解 @Deprecated@DeprecatedSince,用于指定一个方法或接口已被弃用以及自从哪个版本开始弃用。

@Deprecated(since="9.0")
interface MyDeprecatedInterface {
    @Deprecated(since="9.0")
    void deprecatedMethod();
}

三、接口的应用

接口在Java中是一种非常重要的概念,它提供了一种定义方法签名而不实现方法体的方式,这使得接口在Java编程中具有广泛的应用场景和优势。

实现多态: 接口允许类在不同的上下文中具有不同的行为。通过实现相同的接口,不同的类可以按照自己的方式实现接口中的方法,从而实现多态性,增加代码的灵活性和可扩展性。

interface Animal {
    void makeSound();
}

class Dog implements Animal {
    public void makeSound() {
        System.out.println("Woof");
    }
}

class Cat implements Animal {
    public void makeSound() {
        System.out.println("Meow");
    }
}

 实现服务提供者接口: 接口可以用于定义服务的契约,不同的实现类可以提供不同的服务实现。这种模式在插件化和模块化系统中特别有用。

interface DatabaseConnector {
    void connect();
}

class MySQLConnector implements DatabaseConnector {
    public void connect() {
        System.out.println("Connecting to MySQL database...");
    }
}

class PostgreSQLConnector implements DatabaseConnector {
    public void connect() {
        System.out.println("Connecting to PostgreSQL database...");
    }
}

 解耦合: 接口有助于解耦合,即减少代码间的依赖性。程序员可以编写针对接口的代码,而不是具体的实现类,从而使得代码更容易维护和扩展。

interface Logger {
    void log(String message);
}

class FileLogger implements Logger {
    public void log(String message) {
        // Log message to file
    }
}

class ConsoleLogger implements Logger {
    public void log(String message) {
        // Log message to console
    }
}

 实现回调机制: 接口可以用于实现回调机制,即某个对象在特定事件发生时调用另一个对象的方法。这在事件驱动编程和异步处理中非常常见。

interface Callback {
    void onComplete(String result);
}

class Task {
    void execute(Callback callback) {
        // Perform some task and invoke callback
        callback.onComplete("Task completed successfully");
    }
}

函数式接口和Lambda表达式: Java 8 引入了函数式接口的概念,即只包含一个抽象方法的接口。这种接口可以用Lambda表达式来实现,提供了更加简洁和灵活的函数式编程方式。 

@FunctionalInterface
interface MyFunction {
    void perform();
}

public class Main {
    public static void main(String[] args) {
        MyFunction func = () -> System.out.println("Performing function");
        func.perform();
    }
}

四、适配器设计模式

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许接口不兼容的对象可以相互合作。适配器模式通常用于旧接口与新系统之间的适配,或者不同接口之间的适配。

结构和角色

适配器模式涉及以下几个角色:

  • 目标接口(Target): 目标接口是客户端期待使用的接口。客户端通过目标接口与适配器交互,调用在目标接口中定义的方法。

  • 适配器(Adapter): 适配器实现了目标接口,并且包装了一个被适配者(Adaptee)。它将客户端的请求转换为对被适配者的相应调用。

  • 被适配者(Adaptee): 被适配者是原本存在的接口,但它与客户端要求的接口不兼容。适配器通过包装被适配者,使其与客户端能够兼容。

工作原理和应用场景

适配器模式的工作原理是通过创建一个中间层(适配器),将客户端的请求转换为被适配者可以理解的请求。这种模式常见于以下几种情况:

  • 系统升级与兼容:当系统进行升级或者集成时,可能需要与旧系统进行适配,以保证新旧系统能够无缝衔接。

  • 第三方库或组件的使用:当使用第三方库或组件时,其接口可能与当前系统的接口不匹配,需要通过适配器进行适配。

  • 接口的转换:当需要将一个接口转换成另一个接口时,可以使用适配器模式。

示例:

// 目标接口
interface Smartphone {
    void charge();
}

// 被适配者(电子书阅读器)
class EBookReader {
    void powerOn() {
        System.out.println("EBookReader is powering on.");
    }

    void turnPage() {
        System.out.println("EBookReader is turning the page.");
    }
}

// 适配器
class EBookReaderAdapter implements Smartphone {
    private EBookReader reader;

    EBookReaderAdapter(EBookReader reader) {
        this.reader = reader;
    }

    @Override
    public void charge() {
        reader.powerOn();
        System.out.println("Charging EBookReader...");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        EBookReader kindle = new EBookReader();
        Smartphone smartphone = new EBookReaderAdapter(kindle);

        smartphone.charge(); // 使用智能手机充电
    }
}

 在上面的示例中,EBookReader是被适配者,它有自己的一些方法,但是没有charge()方法。通过EBookReaderAdapter适配器,我们实现了Smartphone接口,并在charge()方法中调用了EBookReader的方法,从而将其适配成了一个智能手机可以使用的接口。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值