Java 8 中的抽象类和接口之间有什么区别? [英] What are the differences between abstract classes and interfaces in Java 8?

查看:30
本文介绍了Java 8 中的抽象类和接口之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Java 中,抽象类和接口之间曾经有一个微妙但重要的区别:默认实现.抽象类可以有它们,接口不能.尽管 Java 8 引入了接口的默认实现,这意味着这不再是接口和抽象类之间的关键区别.

In Java there used to be a subtle but important difference between abstract classes and interfaces: default implementations. Abstract classes could have them, interfaces could not. Java 8 though introduces default implementations for interfaces, meaning this is no longer the critical difference between an interface and an abstract class.

那是什么?

据我所知,唯一剩下的区别(除了可能是一些底层效率的东西)是抽象类遵循传统的 Java 单继承,而接口可以具有多重继承(或多重实现,如果你愿意的话)).这让我想到另一个问题 -

As best as I can tell, the only remaining difference (besides perhaps some under the hood efficiency stuff) is that abstract classes follow traditional Java single-inheritance, whereas interfaces can have multiple-inheritance (or multiple-implementation if you will). This leads me to another question -

新的 Java 8 接口如何避免钻石问题?

How do the new Java 8 interfaces avoid the diamond Problem?

推荐答案

接口不能有与其关联的状态.

Interfaces cannot have state associated with them.

抽象类可以有与其关联的状态.

Abstract classes can have state associated with them.

此外,不需要实现接口中的默认方法.所以通过这种方式,它不会破坏已经存在的代码,因为当接口确实收到更新时,实现类不需要实现它.
因此,您可能会得到次优代码,但如果您想拥有更优化的代码,那么您的工作就是覆盖默认实现.

Furthermore, default methods in interfaces need not be implemented. So in this way, it will not break already existing code, as while the interface does receive an update, the implementing class does not need to implement it.
As a result you may get suboptimal code, but if you want to have more optimal code, then your job is to override the default implementation.

最后,如果出现菱形问题,编译器会警告您,需要选择要实现的接口.

And lastly, in case a diamond problem occurs, then the compiler will warn you, and you will need to choose which interface you want to implement.

要详细了解菱形问题,请考虑以下代码:

To show more about the diamond problem, consider the following code:

interface A {
    void method();
}

interface B extends A {
    @Override
    default void method() {
        System.out.println("B");
    }
}

interface C extends A { 
    @Override
    default void method() {
        System.out.println("C");
    }
}

interface D extends B, C {

}

这里我在 interface D extends B, C 上得到编译器错误,即:

Here I get the compiler error on interface D extends B, C, that:

接口 D 继承了 method() 表单类型 B 和 C 的无关默认值

解决方法是:

interface D extends B, C {
    @Override
    default void method() {
        B.super.method();
    }
}

如果我想从 B 继承 method().
如果 Dclass,同样如此.

In case I wanted to inherit the method() from B.
The same holds for if D were a class.

为了进一步了解 Java 8 中接口和抽象类之间的区别,请考虑以下 Team:

To show even more about the difference between interfaces and abstract classes in Java 8, consider the following Team:

interface Player {

}

interface Team {
    void addPlayer(Player player);
}

理论上您可以提供 addPlayer 的默认实现,以便您可以将玩家添加到例如玩家列表中.
但是等等...?
我如何存储玩家列表?
答案是你不能在接口中这样做,即使你有可用的默认实现.

You can in theory provide a default implementation of addPlayer such that you can add players to for example a list of players.
But wait...?
How do I store the list of players?
The answer is that you cannot do that in an interface, even if you have default implementations available.

这篇关于Java 8 中的抽象类和接口之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆