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


当前回答

其实很简单。

您可以将接口视为一个类,它只允许有抽象方法,而不允许有其他方法。

因此,接口只能“声明”而不能定义您希望类具有的行为。

抽象类允许您声明(使用抽象方法)和定义(使用完整方法实现)您希望类具有的行为。

常规类只允许您定义而不是声明您希望类具有的行为/动作。

最后一件事,

在Java中,可以实现多个接口,但只能扩展一个(抽象类或类)。。。

这意味着定义行为的继承被限制为每个类只允许一个。。。例如,如果你想要一个从类a、B和C中封装行为的类,你需要执行以下操作:类a扩展B,类C扩展a。。这是一个有点迂回的方式来拥有多重继承。。。

另一方面,您可以简单地执行接口:接口C实现A、B

因此实际上,Java只在“声明的行为”(即接口)中支持多重继承,并且只支持具有定义行为的单一继承。。除非你像我描述的那样。。。

希望这是合理的。

其他回答

接口只包含功能的定义/签名,如果我们有一些公共功能和公共签名,那么我们需要使用抽象类。通过使用抽象类,我们可以同时提供行为和功能。另一个继承抽象类的开发人员可以很容易地使用这个功能,因为他们只需要填写空白。

摘自:

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.htmlhttp://www.dotnetbull.com/2011/11/what-is-interface-in-c-net.html

我正在建造一座300层的大楼

建筑的蓝图界面

例如,Servlet(I)

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

部分实现,例如泛型和HTTPservlet

建筑施工完成混凝土

完整实现,例如,自己的servlet

界面

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

摘要

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

摘自DurgaJobs网站

php.net上抽象类和接口的简单而有效的解释:

接口就像一个协议。它不指定对象的行为;它指定代码如何告诉该对象的动作。接口类似于英语:定义接口定义代码如何与实现该接口的任何对象通信。接口始终是一个协议或承诺。当一个类说“我实现接口Y”时,它就是说“我承诺拥有与任何具有接口Y的对象相同的公共方法”。另一方面,抽象类类似于部分构建的类。它很像是一个有空格要填写的文档。它可能使用英语,但这并不像某些文档已经写好这样重要。抽象类是另一个对象的基础。当一个类显示“I extend abstract class Y”时,它表示“I use some methods or properties already defined in this other class named Y”。因此,请考虑以下PHP:<?php文件类X实现了Y{}//这意味着“X”同意使用代码使用语言“Y”。类X扩展了Y{}//这意味着“X”将完成部分类“Y”。?>如果您正在分发一个类供其他人使用,那么您的类将实现一个特定的接口。接口是一个协议,为您的类提供一组特定的公共方法。如果您(或其他人)编写了一个已经编写了一些要在新类中使用的方法的类,则可以让您的类扩展一个抽象类。这些概念虽然很容易混淆,但却特别不同和不同。出于所有意图和目的,如果您是任何类的唯一用户,则不需要实现接口。

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

以下示例演示了这一点。

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等。。

唯一的区别是一个可以参与多重继承,另一个不能。

接口的定义随着时间的推移而改变。你认为一个接口只有方法声明,只是契约吗?Java 8之后的静态最终变量和默认定义呢?

由于多重继承的菱形问题,接口被引入到Java中,而这正是它们真正想要做的。

接口是为解决多重继承问题而创建的构造,可以具有抽象方法、默认定义和静态最终变量。

请参阅为什么Java只允许在接口中使用静态最终变量,而这些变量仅用于契约?。