2012-08-07 98 views
0

我有一个抽象类说CTest其中只包含抽象方法f1()而没有别的。同样,我有一个接口ITest与唯一的方法f1()。在这里CTest抽象类和ITest接口都做同样的事情。在这里使用什么,抽象类或接口?

一个区别是,,接口提供了灵活性,它可以在任何已经从其他类派生的类中实现,但抽象类不能。

除了上述差异之外,这两者之间的实际区别是什么?哪一个在这里有效(CTest或ITest)?当我应该使用什么? OO设计中的任何特定场景以及对此的任何一般暗示都很有帮助

+0

你一定很好奇_efficiency_?在Java中,接口方法调用在内部使用['invokeinterface'](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokeinterface)指令,它是[相对昂贵](http://stackoverflow.com/a/1505476/591495)到['invokevirtual'](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6。 HTML#的JVM-6.5.invokevirtual)。 – oldrinb 2012-08-07 05:39:09

+0

看看这可能会帮助你..http://stackoverflow.com/questions/1913098/what-is-the-difference-between-an-interface-and-abstract-class – 2012-08-07 05:42:39

回答

0

对于我来说,最好在这里使用的界面。当你可以在那里提取一些代码时(你可以实现方法或者有其他想调用它的东西),就应该使用抽象类。

0

在这种情况下,假设您的抽象类只包含抽象方法,在我看来,您应该使用接口。具有抽象方法和接口的抽象类可以达到同样的目的,但是,只能扩展一个类,但实现的数量可以任意多,因此,如果您决定继承某些其他类的某些功能,则会使代码不易发生重大更改。

关于你的问题:但这两者之间的实际区别是什么?哪一个在这里有效(CTest或ITest)?当我应该使用什么? OO设计中的任何特定场景以及对此的任何一般暗示都是有帮助的

接口与契约类似,当类实现接口时,它保证了实现。当有人想提供功能但不想泄露内部代码时,这通常会很有帮助,因此开发人员只会抛出接口,以便在不知道每种方法如何实现的情况下进行调用。你可以明显地实现尽可能多的接口,只要你喜欢。

抽象类允许您创建一个具有某些特定行为的类,这些行为是指定的,还有一些类将在未来实现。然而,与接口不同,每个类只能扩展一个类,所以您应该从这个角度谨慎地扩展类。抽象类还允许您将行为注入到一个类,并让它自动通过其子类传播。这通常使开发/维护的某些部分更容易。

+0

另一方面,您可以在不破坏现有代码的情况下对抽象类进行更改。 MSFT的C#最佳实践建议尽可能在设计系统时使用抽象类,以尽量减少未来突破性变化的需求。 – 2012-08-07 05:32:15

+0

@MichaelGraczyk:我同意,因此我在第一行中做了假设:*假定您的抽象类只包含抽象方法*。我将它添加到我的回应的最后一部分,虽然 – npinti 2012-08-07 05:37:15

+0

@ Michael/npinti:我知道我们可以在不改变更改的情况下对抽象类进行更改,但在Interface中不可能。但是,如果你在现有的抽象类中添加一个抽象方法,它仍然会作为接口断开......它是否在这里有任何差异或灵活性? – smhnkmr 2012-08-07 05:41:19

1

Java优选InterfacesAbstract Classes。请参阅第18项中有效的Java

enter image description here

要点

  • 现有的类可以retroffited实现一个新的接口。

  • 接口是定义mixin的理想选择。

  • 接口允许构建非热循环类型的框架。

  • 接口支持安全,强大的功能增强。

2

除继承之外,它取决于场景。检查this code project article是一个很好的例子。

[从文章]

让我们假设你需要三类,首先是汽车,第二是 城域网,第三是女人。现在你需要在他们每个人中定义一个函数来定义 他们如何移动。现在,所有三个人都可以移动,但CAR完全以 不同于MAN和WOMAN的方式移动。所以在这里我们使用一个接口 IMOVEMENT并在其中声明一个函数MOVE。现在所有三个类都可以继承这个接口 。所以班级就是这样。

public interface IMovement 
{ 
    void Move(); 
} 

public class Car : IMovement 
{ 
    public void Move() 
    { 
     //Provide Implementation 
    } 
} 

public class Man : IMovement 
{ 
    public void Move() 
    { 
     //Provide Implementation 
    } 
} 

public class Woman : IMovement 
{ 
    public void Move() 
    { 
     //Provide Implementation 
    } 
} 

但是,因为男人和一个女人走在类似的方式,因此提供相同 行为在两种不同的方法将代码冗余,在简单的 字码不重复使用。所以我们现在可以定义一个人类运动的抽象类,所以这个类可以是人类移动修改。同样 相同可以适用于CAR类,因为有很多 汽车制造商和所有汽车以类似的方式移动,所以我们也可以 定义汽车运动的抽象类可以CARSMOVEMENT。 所以我们重构的代码将会是。

public interface IMovement 
{ 
    void Move(); 
} 

public abstract class CarsMovement : IMovement 
{ 

    public virtual void Move() 
    { 
     //default behavior for cars movement 
    } 
} 

public class SuzukiCar : CarsMovement 
{ 
    public override void Move() 
    { 
     //Provide Implementation 
    } 
} 

public abstract class HumanBeingMovement : IMovement 
{ 

    public virtual void Move() 
    { 
     //default behavior for human being movement 
    } 
} 

public class Man : HumanBeingMovement 
{ 
    public override void Move() 
    { 
     //Provide Implementation 
    } 
} 

public class Woman : HumanBeingMovement 
{ 
    public override void Move() 
    { 
     //Provide Implementation 
    } 
} 
+0

如果有人想知道,那些冒号用于替换“implements”关键字。 – edwga 2012-08-07 05:33:59

+0

@hamad:这个例子很好地解释了接口和抽象类的用法。但就我而言,这两者的实际区别是什么?我应该使用哪一个? – smhnkmr 2012-08-07 05:46:16

+0

@mhn如果你想为所有的派生类实现一些常用的功能,那么你应该在你的情况下使用一个抽象类,如f1()。如果你让f1虚拟,那么这也可以被子类覆盖。另一方面,接口描述了一组可以属于任何类或结构的相关功能。如果没有共同的功能,那么你应该使用接口,因为它通常被理解为如果存在抽象类,那么将会有一些虚拟方法。 – ABH 2012-08-07 07:13:52

0

在这种情况下没有区别,但CTEST类有可能被继承作为一类的唯一类。但是ITest接口可以同时被其他类和接口继承。

0

在你提到的场景中,只有一个方法,它没有定义,最好的方法是界面。

接口在Java中提供的主要优势是可以实现多个接口,但只能扩展一个类。所以,如果你已经扩展了一个抽象类,那么你就没有扩展任何其他类的选项。

黄金法则:接口比抽象类更好,如果我们只需要 定义方法,而不是申报。

话虽如此,接口在你的情况下更好,程序员也应该从未来的角度考虑他的代码。你觉得你正在创建的类/接口将来会有更多的方法吗?你想定义这些方法还是只声明?回答这些问题会让你知道一个接口是否足够或者需要一个抽象类。

0

优势:

抽象类的实现比界面更好,因为方法查找抽象类是不是接口快。如果你修改你的接口,你必须更新你的实现类,但对抽象类进行任何修改,对实现类没有影响。

缺点:

If you want to implement more than one parent class method , it is not possible. 
But regarding to interface you can implement more than one.