如果你有一个只有抽象方法的Abstract类怎么办?这与界面有什么不同?

时间:2013-07-23 12:42:44

标签: c# oop interface abstract-class

根据我的经验,我认为以下是正确的。如果我错过了重点,请告诉我。

接口:

接口中声明的每个单元都必须在子类中实现。接口中只能存在事件,代理,属性(C#)和方法。一个类可以实现多个接口。

抽象类:

只有抽象方法必须由子类实现。 Abstract类可以有实现的常规方法。 Abstract类还可以在Events,Delegates,Properties和Methods旁边有类变量。一个类只能实现一个抽象类,因为C#中不存在多重继承。

所以,即使这种差异也无法解释问题

  

1)如果你的抽象类只有抽象方法怎么办?这与界面有什么不同?

     

2)如果你在界面中有一个Public变量,那么它与Abstract Class有什么不同呢?

所以任何解释都会有所不同。

12 个答案:

答案 0 :(得分:3)

在Java中:

abstract class可以implementinterface

interface 不能 extend abstract class

顺便说一句:奇怪的是 - abstract class可以implementinterface而实际上没有这样做。

interface I {
  public String hello ();
}

interface J {
  public String goodbye ();
}

abstract class A implements I, J {
  @Override
  abstract public String hello ();
}

class B extends A {

  @Override
  public String hello() {
    return "Hello";
  }

  @Override
  public String goodbye() {
    return "goodbye";
  }

}

答案 1 :(得分:3)

接口的所有变量默认为public和static,您不能在接口中只有一个公共变量,而在Abstract类中,您可以声明一个公共变量。

如果一个类扩展了一个Abstract类,它们之间就没有任何契约。扩展它的类可能会或可能不会覆盖抽象方法,但是在接口的情况下,接口和实现它的类之间存在严格的约定,即类必须覆盖该接口的所有方法。因此,从抽象方法的角度来看,它们似乎是相同的,但具有完全不同的属性和优势。

答案 2 :(得分:3)

除了技术差异之外,主要是设计的内涵会导致您决定使用其中一种:

接口定义实现它们的类的公共API 。您使用接口的目标应该是显示实现它的类的用法。这不是副作用,而是一个中心设计目标,类可以实现不同的接口来显示它可以作用的不同角色。

抽象类应该实现一些基本算法常见行为。它主要是在一个地方加入子类的通用功能。其目的是定义内部使用或流,而不是公共接口。如果要发布抽象类的用法,它应该实现一个单独的接口。

所以:

1)使用上述指南时,只有 public 抽象方法的抽象类没有任何意义。抽象类可以定义 protected 抽象方法来定义流或算法。但是接口无法做到这一点。

2)另外,对于公共属性,抽象类可以定义受保护的实例变量,因此有更多的使用场景(参见上面的解释)。

编辑:作者删除了“java”标签。我试图尽可能地使它变得通用,对于java和C#

都应该如此

答案 3 :(得分:2)

虽然你的问题表明它是针对“普通OO”的,但它似乎真正关注.NET对这些术语的使用。

  • 接口可以没有状态或实现
  • 实现接口的类必须提供该接口的所有方法的实现
  • 抽象类可能包含状态(数据成员)和/或实现(方法)
  • 抽象类可以在不实现抽象方法的情况下继承(尽管这样的派生类是抽象的,但是它是非常的)
  • 接口可能是多重继承的,抽象类可能不是(这可能是接口与abtract类分开存在的关键具体原因 - 它们允许实现多重继承,从而消除了一般MI的许多问题)。 / LI>

作为一般的OO术语,差异不一定是明确定义的。例如,有些C ++程序员可能持有类似的严格定义(接口是不能包含实现的抽象类的严格子集),而有些人可能会说具有某些默认实现的抽象类仍然是接口或非抽象接口class仍然可以定义一个接口。

实际上,有一种称为非虚拟接口(NVI)的C ++习惯用法,其中公共方法是非虚拟方法,可以“窃取”私有虚拟方法:

http://www.gotw.ca/publications/mill18.htm http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface

答案 4 :(得分:2)

  

如果你的抽象类只有抽象方法怎么办?怎么样   会不会与界面不同?

  • 您可以实现多个接口,但只能扩展一个类
  • 抽象类对免疫更多,然后更改然后接口,如果你改变一个接口它会破坏实现它的类。
  • 接口只能有static final个字段。抽象类可以包含任何类型的字段。
  • 接口没有构造函数,但抽象类可以拥有它

但是java docs说这个

  

如果抽象类只包含抽象方法声明,那么它   应该声明为接口。

答案 5 :(得分:2)

即使今天的抽象类版本中的所有方法都是抽象的,该类的未来版本也可以添加虚拟或非虚拟方法,而无需强制修改实现或重新编译使用者。相反,将任何成员添加到接口通常需要修改实现接口的所有类以实现该成员,并且无论更改是否添加了尚未实现的任何内容,通常都必须重新编译实现和使用者。

抽象更改可以在不破坏实现或消费者的情况下进行更改这一事实是支持抽象类的一大优势。另一方面,抽象类将强制任何实现类仅从它派生而不是从其他类派生。相比之下,接口几乎会限制其实现者可以继承或派生的内容。这是支持接口的一大优势。

因为抽象类和接口都有明确的优点,所以有时候哪一个可能比另一个好。从概念上讲,可以在界面工作方式中添加一些功能,这样就可以获得目前仅由抽象类提供的优势,但我知道没有特别的计划。

答案 6 :(得分:1)

您的类只能扩展一个抽象类并实现许多接口。

答案 7 :(得分:1)

好吧,在抽象类中你也可以有字段,并且不需要重新实现自动属性。您还可以指定非public的访问说明符。此外,它具有更好的可伸缩性(例如,您可以使用[Obsolete]标记旧实现,然后默认调用旧实现。)此外,它会阻止你再继承类。另一件事是你可以在抽象类中设置静态字段。

此外,界面通常是执行操作的内容,而类是

答案 8 :(得分:1)

*1) What if you had an Abstract class with only abstract methods? How would that be different from an interface?*

默认情况下,接口中的方法是“公共抽象”,抽象类也将抽象方法称为“公共抽象”。  如果抽象类只包含抽象方法,那么最好将它作为一个接口。

*2) What if you had a Public variable inside the interface, how would that be different than in Abstract Class?*

接口不能有变量。如果您的意思是属性,事件,代表等......它们默认为“公共”。如果抽象类中没有指定任何内容,那么它将是“Private”(仅针对接口/抽象类的成员)。

答案 9 :(得分:0)

当您希望班级能够做某事时,使用界面。

当有'is a'关系时,您的类会扩展一个抽象类。

存在语义差异。

答案 10 :(得分:0)

如果是抽象类。

class Dog : abstractAnimal

当我们创建Dog的对象时,我们必须创建abstractAnimal的对象,它将导致额外的对象创建。

如果是界面。

class Dog : IAnimal

当我们创建Dog的对象时,我们不会创建任何额外的任何对象。

答案 11 :(得分:0)

在这种情况下,您可以说:

  

1)我们可以为类中的方法指定不同的访问修饰符,   但是我们无法更改Interface成员的访问修饰符。

     

2)摘要中的派生类不会有强制性   实现。