49

我想知道在什么情况下我们从接口扩展接口?因为,例如

interface A{
    public void method1();
}
interface B extends A{
    public void method2();
}
class C implements B{
    @Override public void method1(){}
    @Override public void method2(){}
}

是不是相当于

interface A{
    public void method1();
}
interface B{
    public void method2();     
}
class C implements A, B{
    @Override public void method1(){}
    @Override public void method2(){}
}

背后有什么重要的原因吗?

4

8 回答 8

73

重要的原因完全取决于接口应该做什么。

如果你有一个 Vehicle 接口和一个 Drivable 接口,那么所有车辆都是可驱动的。如果没有接口继承,每种不同类型的汽车类都将需要

class ChevyVolt implements Vehicle, Drivable
class FordEscort implements Vehicle, Drivable
class ToyotaPrius implements Vehicle, Drivable

等等。

就像我说的所有车辆都是可驾驶的,所以更容易拥有:

class ChevyVolt implements Vehicle
class FordEscort implements Vehicle
class ToyotaPrius implements Vehicle

车辆如下:

interface Vehicle extends Drivable

而且不必考虑。

于 2012-11-18T03:23:31.230 回答
14

是的:它就像在其他任何地方的继承。如果 BA 的特化,那么它应该这样写。第二个表示该类恰好实现了两个接口,它们之间没有任何关系。

从最终结果的角度来看,您可以只使用多个接口来代替处理层次结构(就像您可以避免在类层次结构中使用继承行为一样)。然而,这会使信息更加分散,并且(如果不是更多的话)显着地混淆了软件模型的意图。

于 2012-11-18T03:19:59.410 回答
7

是的,有一个很大的区别。

在您的第一个示例中,您的新接口 B 被定义为从 A 扩展,因此,任何实现 B 的类都会自动实现 A。基本上,您是在告诉编译器“这就是 A 的含义,这就是它的含义意味着是B,哦,顺便说一句,所有B也是A!” 这样你就可以说...

class C implements B {
    ... you implement all of the methods you need...
    ...blah...
    ...blah...
}
A myNewA = new C();

这很好用。

但是,在你的第二个例子中,你没有声明 B 来扩展 A,所以上面的代码不起作用。当您尝试将(第二种)C 的实例分配给 A 的引用时,它会抱怨,因为您没有告诉编译器“所有 B 都是真正的 A”。B(即和之间没有关系C

于 2012-11-18T03:28:02.453 回答
5

中只有一条评论

interface A{
    public void method1();
}
interface B extends A{
    public void method2();
}
class C implements B{
    @Override public void method1(){}
    @Override public void method2(){}
}

如果你声明A a = new C();

你不能调用method2();,因为接口A对接口中的元素一无所知,B即使你在类中实现方法C

于 2019-03-07T13:23:34.190 回答
3

如果你不想在没有实现 A 的情况下实现 B,你可以让 B 扩展 A。

例子:

interface LivingThing{
public void eat();
}

interface Dog extends LivingThing{
public void Bark();
}

不做狗就可以做有生命的东西,但不做活的东西就不可能做狗。因此,如果它可以吠叫,它也可以吃东西,但情况并非总是如此。

于 2014-10-27T20:18:10.367 回答
1

您说的是对的,但不仅仅是完成我们的工作,如果需求是这样的怎么办:

1)假设有10个接口,不是同时设计的。例如 Java 7 中的 AutoCloseable 接口。添加了一个新的自动关闭功能,直到 Java 6 才出现。

2)如果您设计了一个作为标记接口的接口 C,并且您希望从给定类 B 派生的所有类都被标记,那么最好的解决方案是使用 B extends C 而不是将实现 C 放在任何地方。

还有很多原因。如果您查看类和层次结构的更大图景,您可能会自己得到答案。

乐于帮助达拉姆

于 2012-11-18T03:31:23.300 回答
1

有时,您不想允许B没有存在的存在A,而是希望允许存在A而不一定存在B。如果AisCarBis SportCar,您可能只想使用Carinterface 来处理一些流程,但有时需要更具体并明确使用SportCar。这样一来,您就无法决定哪一天只实施SportCar. 它也迫使您实施Car。这正是 OOP 中继承的含义。

此外,假设您想要声明一个新的类成员实现SportCar. 你如何让它也实现Car接口?据我所知,没有办法添加由多个接口组成的类型。

public SportCar myCar;
// public SportCar,Car myCar -> invalid

这样你就不能保证myCar会有一个Car(like Drive()) 的方法,这会失去从继承中获得的优势。

于 2020-03-01T13:32:53.160 回答
0

这里的主要区别在于,在您的第一个示例中,B 是 A,然后是一些。这意味着接口 B 调用 method1() 和 method2(),而在第二个中,A 和 B 是分开的(接口 B 不得出 method1())并且类 C 实现 A 和 B。在这两个实例中,类 C 将覆盖 method1 () 和方法 2()。我希望这有帮助!

于 2013-01-11T01:56:16.163 回答