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


当前回答

如果您有一些可供多个类使用的通用方法,请使用抽象类。否则,如果你想让类遵循某种明确的蓝图,就去寻找接口。

以下示例演示了这一点。

Java中的抽象类:

abstract class Animals
{
    // They all love to eat. So let's implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}
 
class Dog extends Animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}
 
class Cat extends Animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

以下是Java中接口的实现:

interface Shape
{
    void display();
    double area();
}
 
class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 
 
class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

简而言之,一些重要的要点:

默认情况下,Java接口中声明的变量是final。抽象类可以有非final变量。默认情况下,Java接口中声明的变量是静态的。抽象类可以具有非静态变量。默认情况下,Java接口的成员是公共的。Java抽象类可以具有类成员的通常风格,如private、protected等。。

其他回答

抽象类和接口之间的关键技术差异是:

抽象类可以有常量、成员、方法存根(没有主体的方法)和定义的方法,而接口只能有常量和方法存根。抽象类的方法和成员可以以任何可见性定义,而接口的所有方法都必须定义为public(默认情况下定义为public)。继承抽象类时,具体的子类必须定义抽象方法,而抽象类可以扩展另一个抽象类,父类的抽象方法不必定义。类似地,扩展另一个接口的接口不负责从父接口实现方法。这是因为接口不能定义任何实现。子类只能扩展一个类(抽象或具体),而接口可以扩展或类可以实现多个其他接口。子类可以定义具有相同或更少限制性可见性的抽象方法,而实现接口的类必须定义具有完全相同可见性(公共)的方法。

界面:转弯(左转,右转)

抽象类:轮子。

类别:方向盘,衍生自方向盘,暴露接口转向

一个是对可以在各种各样的事物中提供的行为进行分类,另一个是为事物本体建模。

在一个接口中,所有方法都只能是定义,而不能实现单个方法。

但在抽象类中必须有一个只有定义的抽象方法,但其他方法也可以在抽象类的实现中。。。

我迟到10年了,但我想尝试任何方法。几天前写了一篇同样的帖子。我想把它张贴在这里。

tl;博士当您看到“Is A”关系时,请使用继承/抽象类。当您看到“有”关系时,创建成员变量。当您看到“依赖于外部提供程序”时,实现(而不是继承)一个接口。

面试问题:接口和抽象类有什么区别?你如何决定何时使用什么?我通常会得到以下一个或全部答案:答案1:不能创建抽象类和接口的对象。

ZK(这是我的首字母缩写):你不能创建任何一个对象。所以这并不是什么区别。这是接口和抽象类之间的相似之处。柜台问题:为什么不能创建抽象类或接口的对象?

答案2:抽象类可以有一个函数体作为部分/默认实现。

ZK:反问题:所以如果我将其更改为纯抽象类,将所有虚拟函数标记为抽象,并且不为任何虚拟函数提供默认实现。这会使抽象类和接口相同吗?之后它们可以互换使用吗?

答案3:接口允许多重继承,抽象类不允许。

ZK:反问:你真的从接口继承吗?还是只实现一个接口,从抽象类继承?实现和继承之间有什么区别?这些反问题会让考生们措手不及,让大多数人挠头,或者直接进入下一个问题。这让我觉得人们需要帮助来构建面向对象编程的基本构件。原始问题和所有反问题的答案都可以在英语和UML中找到。为了更好地理解这两个结构,您必须至少了解以下内容。

共同名词:共同名词是指同一类或同一种类的事物的“共同”名称。例如水果、动物、城市、汽车等。

专有名词:专有名词是物体、地点或事物的名称。苹果、猫、纽约、本田雅阁等。

汽车是一个通用名词。本田雅阁是一个专有名词,可能是一个合成专有名词,一个由两个名词组成的专有名词。

来到UML部分。您应该熟悉以下关系:

是A有A使用

让我们考虑下面的两句话。-本田雅阁是一辆车?-本田雅阁有车吗?

哪一个听起来正确?简单的英语和理解能力。本田雅阁(HondaAccord)和汽车(Cars)有着“是A”的关系。本田雅阁(Honda accord)没有车,它“是”一辆车。本田雅阁“有一个”音乐播放器。

当两个实体共享“Is A”关系时,它更适合继承。Has a relationship是创建成员变量的更好候选。这样,我们的代码如下所示:

abstract class Car
{
   string color;
   int speed;
}
class HondaAccord : Car
{
   MusicPlayer musicPlayer;
}

现在本田不生产音乐播放器。或者至少这不是他们的主要业务。

因此,他们联系其他公司并签订合同。如果你在这里接收到电源和这两条电线上的输出信号,它在这些扬声器上会播放得很好。

这使得Music Player成为界面的完美候选。你不在乎谁为它提供支持,只要连接正常即可。

您可以用索尼或其他方式替换LG的MusicPlayer。这不会改变本田雅阁的任何事情。

为什么不能创建抽象类的对象?

因为你不能走进展厅说给我一辆车。你必须提供一个专有名词。什么车?可能是本田雅阁。这就是销售代理可以给你东西的时候。

为什么不能创建接口的对象?因为你不能走进展厅说给我一份音乐播放器的合同。这没用。接口位于消费者和提供者之间,只是为了促成协议。你将如何处理协议副本?它不会播放音乐。

为什么接口允许多重继承?

接口未被继承。接口已实现。界面是与外部世界交互的候选界面。本田雅阁有一个加油接口。它有给轮胎充气的接口。和用来给足球充气的软管一样。因此,新代码如下所示:

abstract class Car
{
    string color;
    int speed;
}
class HondaAccord : Car, IInflateAir, IRefueling
{
    MusicPlayer musicPlayer;
}

英文的意思是“本田雅阁是一款支持轮胎充气和加油的汽车”。

我们在接口和抽象类之间存在各种结构/语法差异。还有一些不同之处

[1] 基于场景的差异:

当我们希望限制用户创建父类的对象时,抽象类被用于场景中,并且我们相信将来还会添加更多的抽象方法。

当我们确信不能提供更多抽象方法时,必须使用接口。然后只发布一个接口。

[2] 概念差异:

“我们是否需要在未来提供更多抽象方法”,如果是,则将其设为抽象类,如果否,则设为接口。

(在java 1.7之前最合适和有效)