@Override,接口中使用默认方法

时间:2015-12-06 13:18:31

标签: java interface default

我一直在阅读有关在Java中使用@Override的一些问题。 (例如this one on overridethis one on default methods,显然是documentations)但是,我仍感到困惑。

当一个类需要使用该接口中的所有行为时,我被教导要始终使用和实现接口。我明白了。但是当我被教导时,你会做这样的事情(部分取自文档):

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 :(得分:0)

  

让我烦恼的是接口中方法的实现。它没有做任何事情,它只被声明为一种接受参数的方法,但没有做任何其他事情。

这不是界面"中方法的实现。这只是一个接口方法声明。在编程中,术语很重要。接口往往没有任何实现。 (除非你在讨论Java 8的默认接口方法,但是从你的问题的其余部分来看,目前还不清楚你是否知道它们的存在。)

  

我知道这是一种强迫"实现类的类

一个类无法实现一个类。一个类扩展了一个类。但是一个类实现了一个接口。在编程中,术语很重要。

这不仅仅是一种强制类提供实现的方法。它也是调用者能够调用接口方法而不必了解实现它的类的一种方式。

  

但我不知道这在某些特定用例中是如何有用的。

好吧,以Collection<T>接口和contains()方法为例,该方法由无数类实现,其中ArrayList<T>LinkedList<T>,{{ 1}},HashSet<T>等等,等等。您的代码可能如下所示:

BoundedBlockingQueue<T>

请注意boolean hasPekingese( Collection<Animal> animals ) { return animals.contains( AllOfMyAnimals.PEKINGESE ); } 方法不必知道实现hasPekingese()的确切类。这意味着您可以从保持动物保持在Collection<Animal>的类中调用hasPekingese(),也可以从保持动物保持在ArrayList<Animal>的类中调用hasPekingese() 。方法BoundedBlockingQueue<Animal>不知道,也不关心。

  

我们说我有一个由几个类共享的界面。

目前还不清楚你的意思是&#34;分享&#34;。你是说&#34;实施&#34;?在编程中,术语至关重要。

  

我希望这些类中的大多数共享相同的方法实现,但不是全部。逻辑和字符有效的方法是有一种说法:这些类采用接口中的默认方法,但这些类会覆盖默认方法。我该怎么做呢?

有很多方法可以解决这个问题,最常见的是让一些这些类扩展一些公共基类,它提供了方法的通用实现,这样派生类就会继承这个方法,所以它们不会必须实施它。其余类没有扩展该公共基类,因此每个类都必须提供自己的方法实现。

  

覆盖该方法的那个只应该实现它,而那些只使用默认方法的那个扩展它吗?

那不清楚。另外,请不要将其称为&#34;默认方法&#34;,因为从Java 8&#34;默认方法&#34;是一个具有非常特定含义的术语,虽然它与此讨论有关,但它与您使用它的意义不同。

  

如果您只想在界面中的特定方法中使用此行为,该怎么办?

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

答案 1 :(得分:0)

接口就像API。当某个提供程序为您提供List之类的界面时,您不会考虑它是ArrayList还是其他实现,您只知道可以对此对象执行什么操作。为什么?因为当您提供接口时,您可以稍后更改实现,并且不必担心通过接口使用对象的其他代码部分将需要更改。

我想你会考虑应该将某些行为插入当前类的事情。这些东西在其他编程语言中可以称为Traits,在另一种编程语言中可以称为Traits。如果你想要一些传播到你的类的实现逻辑,你应该在java中使用具有适当层次结构的抽象类。请记住,您可以使用继承或组合(open-closed principle)扩展类。

接口(Java 8)中的默认方法可能很棘手,因为它们无法更改对象的状态。它们可能是一些存根或数学方程,只能用于局部和静态背景。