接口和抽象类之间到底有什么区别?
当前回答
要点:
抽象类可以具有属性、数据字段、方法(完整/不完整)。如果方法或财产在抽象关键字中定义,则必须在派生类中重写该关键字。(它作为一个紧密耦合的功能)如果为抽象类中的方法或财产定义抽象关键字,则无法定义方法体和获取/设置的值必须在派生类中重写的财产。抽象类不支持多重继承。抽象类包含构造函数。抽象类可以包含子、函数和财产的访问修饰符。只有抽象类的完整成员可以是静态的。接口只能从另一个接口继承,不能从抽象类继承,其中抽象类可以从另一抽象类或其他接口继承。
优势:
它是一种强制所有子类执行相同层次结构或标准的契约。如果各种实现都是相同的类型,并且使用共同的行为或状态,那么抽象类更适合使用。如果我们向抽象类添加一个新方法,那么我们可以选择提供默认实现,因此所有现有代码都可以正常工作。它允许比接口更快的执行。(接口需要更多时间在相应的类中查找实际方法。)它可以用于紧耦合和松耦合。
在此处查找详细信息。。。http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/
其他回答
简而言之,差异如下:
接口和抽象类之间的语法差异:
抽象类的方法和成员可以具有任何可见性。接口的所有方法都必须是公共的//Java 9不再适用抽象类的具体子类必须定义所有抽象方法。抽象子类可以具有抽象方法。扩展另一个接口的接口不需要为从父接口继承的方法提供默认实现。子类只能扩展单个类。一个接口可以扩展多个接口。一个类可以实现多个接口。子类可以定义具有相同或更少限制性可见性的抽象方法,而实现接口的类必须将所有接口方法定义为公共的。抽象类可以有构造函数,但不能有接口。来自Java9的接口具有私有静态方法。
现在在界面中:
公共静态-支持公共摘要-支持公共默认值-支持私有静态-支持私有抽象-编译错误私有默认值-编译错误私有-支持
抽象类和接口之间的关键技术差异是:
抽象类可以有常量、成员、方法存根(没有主体的方法)和定义的方法,而接口只能有常量和方法存根。抽象类的方法和成员可以以任何可见性定义,而接口的所有方法都必须定义为public(默认情况下定义为public)。继承抽象类时,具体的子类必须定义抽象方法,而抽象类可以扩展另一个抽象类,父类的抽象方法不必定义。类似地,扩展另一个接口的接口不负责从父接口实现方法。这是因为接口不能定义任何实现。子类只能扩展一个类(抽象或具体),而接口可以扩展或类可以实现多个其他接口。子类可以定义具有相同或更少限制性可见性的抽象方法,而实现接口的类必须定义具有完全相同可见性(公共)的方法。
如果您有一些可供多个类使用的通用方法,请使用抽象类。否则,如果你想让类遵循某种明确的蓝图,就去寻找接口。
以下示例演示了这一点。
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等。。
通常抽象类用于某些东西的核心,但接口用于附加外围设备。
当您想为车辆创建基本类型时,应该使用抽象类,但如果您想添加一些不属于车辆基本概念的功能或属性,则应该使用接口,例如,您想添加“ToJSON()”函数。
接口具有广泛的抽象范围,而不是抽象类。您可以在传递的论证中看到这一点。请查看以下示例:
如果您使用vehicle作为参数,您可以使用它的派生类型之一(公共汽车或汽车同一类别只是车辆类别)。但当您使用IMoveable接口作为参数时,您有更多的选择。
我正在建造一座300层的大楼
建筑的蓝图界面
例如,Servlet(I)
建筑高达200层-部分完工-摘要
部分实现,例如泛型和HTTPservlet
建筑施工完成混凝土
完整实现,例如,自己的servlet
界面
我们对实现一无所知,只知道需求。我们可以去找一个接口。默认情况下,每个方法都是公共的和抽象的这是一个100%纯抽象类如果我们宣布公开,我们就不能宣布隐私和受保护如果我们声明抽象,我们就不能声明final、static、synchronized、strictfp和native每个接口都有公共的、静态的和最终的序列化和瞬态不适用,因为我们无法在接口中创建实例非挥发性,因为它是最终的每个变量都是静态的当我们在接口内声明变量时,我们需要在声明不允许实例和静态块
摘要
部分实施它有一个抽象的方法。此外,它使用混凝土对抽象类方法修饰符没有限制抽象类变量修饰符没有限制除了abstract,我们不能声明其他修饰符初始化变量没有限制
摘自DurgaJobs网站