@Override,带有默认方法的接口

3
我是一名有用的助手,可以为您翻译文本。

我一直在阅读关于Java中@ Override使用的一些问题。 (例如这个关于override的问题这个关于默认方法的问题,以及显然的文档) 然而,我仍然感到困惑。

我被教导要始终在类中使用和实现接口,当该接口中的所有行为都需要被类使用时。我明白了。但是,就像我所学到的那样,您会执行以下操作(部分摘自文档):

public interface TimeClient {
    void setTime(int hour, int minute, int second);
}

然后由一个类来实现。
public class TestSimpleTimeClient implements TimeClient {
    public static void main(String[] args) {
    }

    @Override
    public void setTime(int hour, int minute, int second) {
         System.out.println(hour + " " + minute + " " +second);
    }
}

我困扰的是接口中方法的实现。它并不做任何事情,只是声明了一个带参数的方法,但没有其他操作。然后你在实现该接口的类中覆盖该方法。
我知道这是一种“强制”类实现方法的方式,但我不明白在某些特定用例中它有什么用处。
比方说,我有一个接口由几个类实现。我想让大多数这些类共享方法的相同实现,但不是全部。逻辑上和字符效率最高的方法是有一种方法来说明:这些类采用接口中的默认方法,而这些类覆盖默认方法。我该如何做到这一点?覆盖方法的那个类是否只需实现它,而那些简单使用默认方法的类则需要扩展它?如果你只想在接口的特定方法中使用此行为,该怎么办?
2个回答

0
让我困扰的是接口中方法的实现。它什么也不做,只是声明了一个带参数但不执行任何其他操作的方法。
这不是“接口中方法的实现”。这只是一个接口方法声明。在编程中,术语很重要。接口往往缺乏任何实现。(除非你谈论的是Java 8的默认接口方法,但从你问题的其余部分来看,你是否知道它们的存在还不清楚。)
我知道这是一种“强制”类实现一个类的方式。
一个类不能实现一个类。一个类继承一个类。但是一个类可以实现一个接口。在编程中,术语非常重要。
这不仅是一种强制类提供实现的方式,还是调用者能够调用接口方法而无需知道实现它的类的任何信息的一种方式。
但我不明白在某些特定用例中如何使用它。

比如说,我们来看一下 Collection<T> 接口和 contains() 方法。这个方法被很多类实现,包括 ArrayList<T>LinkedList<T>HashSet<T>BoundedBlockingQueue<T> 等等。你的代码可能会像这样:

boolean hasPekingese( Collection<Animal> animals )
{
    return animals.contains( AllOfMyAnimals.PEKINGESE );
}

请注意,hasPekingese()方法不必知道实现Collection<Animal>的确切类。这意味着您可以从将其动物保存在ArrayList<Animal>中的类中调用hasPekingese(),也可以从将其动物保存在BoundedBlockingQueue<Animal>中的类中调用hasPekingese()。该方法hasPekingese()不知道,也不关心。

假设我有一个接口被几个类共享。

不清楚您所说的“共享”是什么意思。您是否指“实现”?在编程中,术语至关重要。

我希望大多数这些类共享方法的相同实现,但并非全部。逻辑上和字符高效的方法是有一种方式来表明:这些类采用接口中的默认方法,但这些类覆盖默认方法。我该如何做到这一点?

有很多方法可以实现这个,最常见的是让一些类继承一个共同的基类,该基类提供了你的方法的通用实现,因此派生类继承了这个方法,所以它们不需要实现它。其余的类不继承这个共同的基类,因此每个类都必须提供自己的方法实现。

如果只有覆盖该方法的类实现它,而那些仅使用默认方法的类则全部继承它,这样做是否合适?

这并不清楚。另外,请不要称其为“默认方法”,因为从Java 8开始,“默认方法”是一个具有非常特定含义的术语,虽然它与本讨论相关,但它与您使用的意义不同。

如果您只想在接口中的特定方法中实现此行为怎么办?

如果派生类希望该方法以不同的方式工作,则可以重新覆盖它。或者,您可以拥有两个不同的基类,一个以某种方式实现该方法,另一个以不同的方式实现该方法,因此您的派生类的一半继承第一个基类,而另一半继承第二个基类。


0

接口就像API一样。当某个提供者给你一个像List这样的接口时,你不需要考虑它是ArrayList还是其他实现方式,你只需要知道你可以用这个对象做什么。为什么?因为当你提供一个接口时,你可以在以后改变实现方式,而不必担心使用该对象的代码的其他部分需要更改。

我想你会考虑一些应该插入到当前类中的行为。在其他编程语言中,这些东西可以称为Traits,在另一种语言中,你有多重继承。如果你想要一些已实现的逻辑被传播到你的类中,你应该使用Java中的抽象类和适当的层次结构。记住,你可以通过继承或组合(开闭原则)来扩展类。

接口中的默认方法(Java 8)可能会很棘手,因为它们不能改变对象的状态。它们可能是一些存根或数学方程,只能与本地和静态上下文一起使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接