接口和抽象类之间有什么区别?

接口和抽象类之间到底有什么区别?

答案

介面

接口是一种契约 :编写接口的人说:“ 嘿,我接受那样的事情 ”,而使用接口的人说:“ 好,我编写的类看起来就这样 ”。

接口是一个空壳 。这些方法只有签名,这意味着这些方法没有主体。该界面无法执行任何操作。这只是一个模式。

例如(伪代码):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }


    int getFuel()
    {
        return this.fuel;
    }
}

实现一个接口消耗的 CPU 很少,因为它不是一个类,而是一堆名称,因此不需要执行任何昂贵的查找。当它很重要时,例如在嵌入式设备中,它很棒。


抽象类

与接口不同,抽象类是类。它们的使用成本更高,因为从它们继承后需要进行查找。

抽象类看起来很像接口,但是它们还有更多的功能:您可以为其定义行为。更多的是一个人在说,“ 这些类应该看起来像那样,它们具有共同点,所以要填空! ”。

例如:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

实作

虽然抽象类和接口应该是不同的概念,但实现有时会使该陈述不正确。有时,它们甚至不是您认为的那样。

在 Java 中,此规则得到了严格执行,而在 PHP 中,接口是抽象类,没有声明任何方法。

在 Python 中,抽象类更多是一种可从 ABC 模块获得的编程技巧,实际上是在使用元类,因此也使用类。接口与这种语言中的鸭子类型更相关,它是约定和调用描述符的特殊方法(__method__方法)之间的混合。

和编程一样,理论,实践和实践都是另一种语言:-)

抽象类接口之间的主要技术区别是:

  • 抽象类可以具有常量,成员,方法存根(没有主体的方法)和已定义的方法 ,而接口只能具有常量方法存根

  • 可以以任何可见性定义抽象类的方法和成员,而接口的所有方法都必须定义为public (默认情况下,它们定义为public )。

  • 继承抽象类时, 具体的子类必须定义抽象方法 ,而抽象类可以扩展另一个抽象类,而不必定义父类的抽象方法。

  • 同样,扩展另一个接口的接口也不负责从父接口实现方法 。这是因为接口无法定义任何实现。

  • 子类只能扩展一个类 (抽象或具体),而一个接口可以扩展或一个类可以实现多个其他接口

  • 子类可以定义具有相同或更少限制性可见性的抽象方法,而实现接口的类必须定义具有完全相同的可见性(公共)的方法。

接口仅包含功能的定义 / 签名,如果我们具有一些通用功能和通用签名,则需要使用抽象类。通过使用抽象类,我们可以同时提供行为和功能。另一个继承抽象类的开发人员可以轻松使用此功能,因为他们只需要填写空白即可。

在此处输入图片说明摘自:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in -c-net.html

可以在这里找到说明: http : //www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

抽象类是仅由程序员部分实现的类。它可能包含一个或多个抽象方法。抽象方法只是一个函数定义,用于告诉程序员该方法必须在子类中实现。

接口类似于抽象类。实际上,接口与类和抽象类占用相同的名称空间。因此,您不能定义与类同名的接口。接口是一个完全抽象的类;它的任何方法均未实现,并且据说不是从该方法子类继承而来,而是实现了该接口。

无论如何,我发现对接口的这种解释有些令人困惑。一个更常见的定义是: 接口定义实现类必须满足的协定。接口定义由公共成员的签名组成,没有任何实现代码。

我不想强调差异,在许多答案中已经提到了差异(关于接口中变量的公共静态最终修饰符以及对抽象类中受保护的私有方法的支持)

简单来说,我想说:

接口:由多个不相关的对象实施合同

抽象类:在多个相关对象之间实现相同或不同的行为

从 Oracle 文档

如果满足以下条件, 请考虑使用抽象类

  1. 您想在几个紧密相关的类之间共享代码。
  2. 您期望扩展您的抽象类的类具有许多公共方法或字段,或者需要除 public(例如 protected 和 private)之外的访问修饰符。
  3. 您要声明非静态或非最终字段。

如果满足以下条件, 请考虑使用接口

  1. 您期望不相关的类将实现您的接口。例如,许多不相关的对象可以实现Serializable接口。
  2. 您想指定特定数据类型的行为,但不关心谁实现了它的行为。
  3. 您想利用类型的多重继承。

抽象类与具体类建立 “是” 关系。接口为类提供 “具有” 功能。

如果您正在寻找将Java作为编程语言,则这里有一些其他更新:

Java 8 通过提供default方法功能在某种程度上减少了interfaceabstract类之间的差距。 接口没有实现的方法不再有效。

有关更多详细信息,请参考此文档页面

请看一下这个 SE 问题,以获取更好的代码示例。

我应该如何解释接口和抽象类之间的区别?

一些重要的区别:

以表格的形式:

区别

正如javapapers 的 Joe 所说

1. 主要区别在于 Java 接口的方法是隐式抽象的,无法实现。 Java 抽象类可以具有实现默认行为的实例方法。

2. Java 接口中声明的变量默认为 final。抽象类可能包含非最终变量。

3. Java 接口的成员默认情况下是公共的。 Java 抽象类可以具有类成员的常用风格,例如 private,protected 等。

4.Java 接口应使用关键字 “implements” 来实现; Java 抽象类应使用关键字 “extends” 进行扩展。

5. 一个接口只能扩展另一个 Java 接口,一个抽象类可以扩展另一个 Java 类并实现多个 Java 接口。

6.Java 类可以实现多个接口,但只能扩展一个抽象类。

7,接口绝对是抽象的,不能实例化; Java 抽象类也无法实例化,但是可以在存在 main()的情况下调用。

8,与 Java 抽象类相比,Java 接口比较慢,因为它需要额外的间接调用。

要点是:

  • 抽象是面向对象的 。它提供 “对象” 应具有的基本数据和 / 或它应具有的功能。它与对象的基本特征有关:它具有什么以及它可以做什么。因此,从相同抽象类继承的对象具有基本特征(泛化)。
  • 接口是面向功能的 。它定义了对象应具有的功能。不管它是什么对象,只要它可以执行接口中定义的这些功能,就可以了。它忽略了其他所有内容。一个对象 / 类可以包含几个(组)功能。因此,一个类可以实现多个接口。

如果要在继承层次结构中提供多态行为,请使用抽象类。

当您想要完全不相关的类的多态行为时,请使用一个接口。

我正在建造一个 300 层的建筑物

建筑物的蓝图界面

  • 例如,Servlet(I)

建筑高达 200 层 - 部分完成 --- 摘要

  • 部分实现,例如,通用和 HTTP Servlet

建筑施工完成 - 混凝土

  • 完整的实现,例如拥有自己的 servlet

接口

  • 我们对实现一无所知,对需求一无所知。我们可以去找一个界面。
  • 默认情况下,每种方法都是公共的和抽象的
  • 这是一个 100%纯的抽象类
  • 如果我们宣布公开,我们就不能宣布私有和受保护
  • 如果声明抽象,则无法声明 final,static,synchronized,strictfp 和 native
  • 每个接口都有公共,静态和最终接口
  • 序列化和暂态不适用,因为我们无法在 in 接口中创建实例
  • 非易失性的,因为它是最终的
  • 每个变量都是静态的
  • 当我们在接口内声明变量时,我们需要在声明时初始化变量
  • 实例和静态块不允许

抽象

  • 部分实施
  • 它具有抽象方法。另外,它使用混凝土
  • 对抽象类方法修饰符没有限制
  • 对抽象类变量修饰符没有限制
  • 除了抽象,我们不能声明其他修饰符
  • 没有初始化变量的限制

摘自 DurgaJobs 网站

让我们再次解决这个问题:

首先要知道的是 1/1 和 1 * 1 的结果相同,但这并不意味着乘法和除法相同。显然,他们之间保持着良好的关系,但是请注意你们俩是不同的。

我将指出主要的区别,其余的都已经解释了:

抽象类对于建模类层次结构很有用。在任何要求乍看之下,我们对到底什么是待建部分透明的,但我们知道如何构建。因此,您的抽象类就是您的基类。

接口可用于让其他层次结构或类知道我的能力。当你说我有能力的时候,你必须具备这种能力。接口会将其标记为类必须实施相同的功能。