如果你有一个只有抽象方法的抽象类会怎样?这与界面有何不同

本文关键字:何不同 界面 抽象类 有一个 抽象方法 如果 | 更新日期: 2023-09-27 18:24:20

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

接口:

接口中声明的每个方法都必须在子类中实现。接口中只能存在事件、委托、属性 (C#( 和方法。一个类可以实现多个接口。

抽象类:

只有抽象方法必须由子类实现。抽象类可以具有带有实现的普通方法。抽象类还可以在事件、委托、属性和方法旁边有类变量。一个类只能实现一个抽象类,因为 C# 中不存在多重继承。

因此,即使这种差异也无法解释这个问题。

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

2(如果你在接口中有一个公共变量,它与抽象类有什么不同?

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

如果你有一个只有抽象方法的抽象类会怎样?这与界面有何不同

除了技术差异之外,主要是您的设计意图应该导致您决定使用其中一个:

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

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

所以:

1(当您使用上述准则时,只有公共抽象方法的抽象类没有任何意义。抽象类可以定义受保护的抽象方法来定义流或算法。但这在接口上是不可能的。

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

编辑:"java"标签已被作者删除。我试图使它尽可能通用,对于java和C#

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"; } }

默认情况下,接口的所有变量都是公共和静态的,接口中不能只有一个公共变量,而在抽象类中,您可以声明一个公共变量。

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

虽然您的问题表明它是针对"通用 OO"的,但它似乎确实侧重于 .NET 使用这些术语。

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

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

事实上,有一种称为非虚拟接口 (NVI( 的C++习语,其中公共方法是"扔"到私有虚拟方法的非虚拟方法:

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

如果你有一个只有抽象方法的抽象类会怎样?如何 这与界面会有所不同吗?

  • 您可以实现多个接口,但只能扩展一个类
  • 抽象类比接口更不受更改的影响,因为如果您更改接口,它将破坏实现它的类。
  • 接口只能有static final字段。抽象类可以有任何类型的字段。
  • 接口没有构造函数,但抽象类可以有它

但是Java文档是这样说的

如果抽象类仅包含抽象方法声明,则 应改为声明为接口。

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

抽象

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

因为抽象类和接口都有明确的优势,所以有时任何一个可能比另一个更好。 从概念上讲,可以在接口的工作方式中添加一些功能,使它们具有目前只有抽象类才能享有的优势,但我知道没有特别的计划这样做。

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

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

此外,接口通常是执行操作的东西,而类则是关于执行操作的东西

*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?*

接口不能有变量。如果您指的是属性、事件、委托等...默认情况下,它们将是"公共"。如果抽象类中未指定任何内容,则为"私有"(仅针对接口/抽象类的成员(。

当您希望类能够执行某些操作时,将使用接口。

当存在'is a'关系时,您的类将扩展抽象类。

存在语义差异。

在抽象类的情况下。

class Dog : abstractAnimal

当我们创建 Dog 的对象时,我们将不得不创建抽象动物的对象,这将导致额外的对象创建。

在接口的情况下。

class Dog : IAnimal

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

在这种情况下,

你可以说:

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

2(从抽象派生的类不会有强迫 实现。