JavaSE_8系列博客——Java语言的特性(五)--接口和继承(6)--默认方法的使用场景

本文探讨了在接口中使用默认方法的概念,特别是在向现有接口添加新功能时如何保持向后兼容性。通过具体示例展示了默认方法如何帮助简化代码更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么实用默认方法?场景如下

本章节:描述了一个例子,涉及计算机控制汽车的制造商,他们发布行业标准接口,描述哪些方法可以被调用来操作他们的汽车。如果这些电脑控制的汽车制造商将新的功能(如飞行)添加到他们的汽车怎么办?

这些制造商将需要指定新的方法,使其他公司(如电子指导仪器制造商)能够使其软件适应飞行汽车。这些汽车制造商会在哪里申报这些新的与飞行有关的方法?

如果将它们添加到原始接口,那么实现这些接口的程序员将不得不重写其实现。如果他们将它们添加为静态方法,那么程序员将它们视为实用方法,而不是基本的核心方法。

默认方法使您能够向库的接口添加新功能,并确保与旧版本的这些接口编写的代码的二进制兼容性。

考虑以下接口,TimeClient:

import java.time.*; 

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();
}

以下类SimpleTimeClient实现了TimeClient:

package defaultmethods;

import java.time.*;
import java.lang.*;
import java.util.*;

public class SimpleTimeClient implements TimeClient {

    private LocalDateTime dateAndTime;

    public SimpleTimeClient() {
        dateAndTime = LocalDateTime.now();
    }

    public void setTime(int hour, int minute, int second) {
        LocalDate currentDate = LocalDate.from(dateAndTime);
        LocalTime timeToSet = LocalTime.of(hour, minute, second);
        dateAndTime = LocalDateTime.of(currentDate, timeToSet);
    }

    public void setDate(int day, int month, int year) {
        LocalDate dateToSet = LocalDate.of(day, month, year);
        LocalTime currentTime = LocalTime.from(dateAndTime);
        dateAndTime = LocalDateTime.of(dateToSet, currentTime);
    }

    public void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second) {
        LocalDate dateToSet = LocalDate.of(day, month, year);
        LocalTime timeToSet = LocalTime.of(hour, minute, second); 
        dateAndTime = LocalDateTime.of(dateToSet, timeToSet);
    }

    public LocalDateTime getLocalDateTime() {
        return dateAndTime;
    }

    public String toString() {
        return dateAndTime.toString();
    }

    public static void main(String... args) {
        TimeClient myTimeClient = new SimpleTimeClient();
        System.out.println(myTimeClient.toString());
    }
}

假设您要向TimeClient接口添加新功能,例如通过ZonedDateTime对象(除了存储时区信息之外的类似于LocalDateTime对象)指定时区的功能:

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
        int hour, int minute, int second);
    LocalDateTime getLocalDateTime();                           
    ZonedDateTime getZonedDateTime(String zoneString);
}

在对TimeClient接口进行此修改后,您还必须修改SimpleTimeClient类并实现getZonedDateTime方法。但是,不是将getZonedDateTime作为抽象的方法,您可以改为定义默认实现。 (记住一个抽象方法是一个声明为没有实现的方法。)

package defaultmethods;

import java.time.*;

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();

    static ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

您指定接口中的方法定义是在方法签名开头的default关键字的默认方法。接口中的所有方法声明(包括默认方法)都是隐式公开的,因此可以省略public修饰符。 使用此接口,您不必修改SimpleTimeClient类,并且此类(以及实现接口TimeClient的任何类)将具有已定义的方法getZonedDateTime。

以下示例TestSimpleTimeClient从SimpleTimeClient的实例调用getZonedDateTime方法:

package defaultmethods;

import java.time.*;
import java.lang.*;
import java.util.*;

public class TestSimpleTimeClient {
    public static void main(String... args) {
        TimeClient myTimeClient = new SimpleTimeClient();
        System.out.println("Current time: " + myTimeClient.toString());
        System.out.println("Time in California: " +
            myTimeClient.getZonedDateTime("Blah blah").toString());
    }
}
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值