当前位置: 首页 > 知识库问答 >
问题:

为什么我们需要Java中的默认方法?[副本]

史洛城
2023-03-14

我看了一下Java8与7相比的新闻,除了lambdas或新的时间框架等非常有趣的东西之外,我发现一个新特性(?)介绍了:默认方法。

我在这篇文章中发现了以下示例:

public interface Math {

    int add(int a, int b);

    default int multiply(int a, int b) {
        return a * b;
    }
}

在我看来很奇怪。上面的代码看起来像一个具有已实现方法的abstract类。那么,为什么要在一个接口中引入默认方法呢?这种做法的实际好处是什么?

在同一篇文章中,我读到了这样的解释:

为什么要在接口中添加方法?这是因为接口与它们的实现类耦合得太紧了。即在接口中添加一个方法而不破坏implementor类是不可能的。一旦在接口中添加了一个方法,它的所有实现类都必须声明这个新方法的方法体。

这一点也不能说服我。因此,我认为,当一个类实现一个接口时,显然必须为其中的每个方法声明methods body。这当然是一种限制,但也是对其“性质”的确认(如果你明白我的意思的话……)

如果您对每个继承类都有公共逻辑,那么您将把它放入一个实现的abstract类中。

那么,默认方法的真正优势是什么呢?(看起来更像是变通办法,而不是新功能……)

更新我理解这种方法是为了向后兼容,但它仍然不能说服我那么多。接口表示类必须具有的行为。因此实现某个接口的类肯定会有这种行为。但如果有人可以任意更改接口,这一约束就被打破了。行为会随时改变...我错了吗?

共有1个答案

常彭薄
2023-03-14

这是为了向后兼容。

如果您有一个其他人已经实现的接口,那么如果您向该接口添加了一个新方法,那么所有现有的实现都将被破坏。

通过添加一个具有默认实现的新方法,您将保持与现有实现的源代码兼容。

对于一个稍微简单/做作的示例,我们假设您创建了一个库:

void drawSomething(Thing thing) {
}

interface Thing {
    Color getColor();
    Image getBackgroundImage();
}

现在,您要完成库的新版本,并且希望添加边框颜色的概念,这很容易添加到界面中:

interface Thing {
    Color getColor();
    Color getBorderColor();
    Image getBackgroundImage();
}

但问题是,每个使用库的人都必须返回他们曾经做过的每个皮肤实现,然后添加这个新方法。

相反,如果您为GetBorderColor提供了一个默认实现,它只是调用了GetColor,那么所有东西都“正常工作”。

 类似资料:
  • 我正在阅读有关java中的同步概念的信息,并遇到了同步语句。 我想知道,为什么我们向它传递参数,尽管它看起来像静态块(这只是一个例子),并且传递的参数没有指定任何数据类型。 例: 如果有人知道,请解释。

  • 问题内容: 我知道弱引用是垃圾收集器的摆布,我们不能保证弱引用会存在。我认为没有必要提供较弱的参考,但可以确定应该有一个理由。 为什么我们需要Java中的弱引用? Java中弱引用的实际(某些)用法是什么?如果您可以分享您在项目中的使用方式,那就太好了! 问题答案: 使用弱哈希图实际上通常是一个坏主意。首先,很容易出错,但更糟糕的是,它通常用于实现某种缓存。 这意味着以下内容:您的程序在一段时间内

  • 问题内容: Angular应用使用属性而不是事件。 为什么是这样? 问题答案: ng-click包含一个角度表达式。Angular表达式是在Angular 范围的上下文中求值的,该范围绑定到具有ng- click属性的元素或该元素的祖先。 Angular表达式语言不包含流控制语句,也不能声明变量或定义函数。这些限制意味着模板只能访问由控制器或指令提供的变量和运行功能。

  • 以我的拙见,关于“什么是单子”这个著名问题的答案,尤其是投票最多的答案,试图解释什么是单子,而没有明确解释为什么单子是真正必要的。它们能被解释为一个问题的解决方案吗?

  • 为什么我们需要字典? 计算机最适合使用数字,而人类最适合使用姓名。我们创建了DNS以便记住主机名而不是IP地址。字典以相同的方式使用,因此我们可以记住AVP名称而不是类型编号。当FreeRADIUS解析请求或生成响应时,会查阅字典。 但是,字典与DNS不同,因为RADIUS客户端不知道FreeRADIUS使用的这些“友好”名称。永远不会在RADIUS客户端和RADIUS服务器之间交换AVP名称。