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


当前回答

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

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

其他回答

接口通常是没有逻辑的类,只有签名。而抽象类是具有逻辑的类。两者都支持作为接口的契约,所有方法都应该在子类中实现,但在抽象中只应该实现抽象方法。何时使用接口,何时抽象?为什么使用界面?

class Circle {

protected $radius;

public function __construct($radius)

{
    $this->radius = $radius
}

public function area()
{
    return 3.14159 * pow(2,$this->radius); // simply pie.r2 (square);
}

}

//Our area calculator class would look like

class Areacalculator {

$protected $circle;

public function __construct(Circle $circle)
{
    $this->circle = $circle;
}

public function areaCalculate()
{
    return $circle->area(); //returns the circle area now
}

}

我们只需要

$areacalculator = new Areacalculator(new Circle(7)); 

几天后,我们将需要矩形、正方形、四边形等区域。如果是这样,我们是否必须每次更改代码并检查实例是正方形、圆形还是矩形?现在OCP所说的是接口代码而不是实现。解决方案是:

Interface Shape {

public function area(); //Defining contract for the classes

}

Class Square implements Shape {

$protected length;

public function __construct($length) {
    //settter for length like we did on circle class
}

public function area()
{
    //return l square for area of square
}

Class Rectangle implements Shape {

$protected length;
$protected breath;

public function __construct($length,$breath) {
    //settter for length, breath like we did on circle,square class
}

public function area()
{
    //return l*b for area of rectangle
}

}

现在是面积计算器

class Areacalculator {

$protected $shape;

public function __construct(Shape $shape)
{
    $this->shape = $shape;
}

public function areaCalculate()
{
    return $shape->area(); //returns the circle area now
}

}

$areacalculator = new Areacalculator(new Square(1));
$areacalculator->areaCalculate();

$areacalculator = new Areacalculator(new Rectangle(1,2));
$areacalculator->;areaCalculate();

这不是更灵活吗?如果我们在没有接口的情况下进行编码,我们将检查每个形状冗余代码的实例。

现在什么时候使用抽象?

Abstract Animal {

public function breathe(){

//all animals breathe inhaling o2 and exhaling co2

}

public function hungry() {

//every animals do feel hungry 

}

abstract function communicate(); 
// different communication style some bark, some meow, human talks etc

}

现在,当一个人不需要那个类的实例,具有类似的逻辑,需要契约时,应该使用抽象。

总结起来最简单的方法是:

完全抽象,除了默认和静态方法;虽然它有默认和静态方法的定义(方法签名+实现),但它只有其他方法的声明(方法签名)。受比类更宽松的规则约束(类可以实现多个接口,接口可以从多个接口继承)。所有变量都是隐式常量,无论是否指定为公共静态final。所有成员都是隐式公共的,无论是否指定为公共成员。通常用于保证实现类将具有指定的特性和/或与实现相同接口的任何其他类兼容。

同时,抽象类是:

从完全抽象到完全实现,具有一个或多个抽象方法的倾向。可以包含声明和定义,声明标记为抽象。一个完整的类,并且受制于管理其他类的规则(只能从一个类继承),条件是它不能实例化(因为不能保证它完全实现)。可以具有非常量成员变量。可以实现成员访问控制,将成员限制为受保护、私有或私有包(未指定)。通常用于提供可由多个子类共享的尽可能多的实现,或者提供程序员能够提供的尽可能的实现。

或者,如果我们想将其归结为一句话:接口是实现类所拥有的,而抽象类是子类所拥有。

之所以调用接口,是因为它向调用方(例如COM客户端)提供了由某个类实现的方法接口。通过将一个对象指针以多态的方式投射到对象类实现的接口的类型,它限制对象对其实现的接口中的函数和成员的访问,与coclass可能实现的其他COM接口分离。客户端不需要知道什么类实现了接口,或者该类中存在什么其他方法;对象以它所知道的接口实例的形式呈现(其中类的实例已被多态地转换为接口实例,该接口实例是类的子实例),它只是通过调用接口实例上的接口方法来使用接口。实际实现的所有细节和不同接口实现的无关功能/细节都与调用方期望的接口分离——调用方只使用它与对象的接口(接口实例及其作为对象一部分的虚拟表指针),并且调用底层对象实现,而调用者不必知道实现的位置或细节。通过接口(接口类型的指针)访问对象是一种封装形式,在语法上防止未经授权访问对象,并隐藏实现细节和其他与接口及其定义的个性无关的功能。

接口是所有方法都是虚拟和抽象的(抽象在C++中称为纯虚拟;所有抽象方法都包含虚拟说明符,因此是虚拟的)。抽象类是指至少有一个方法是虚拟的,并指定为抽象的(或C++中的纯虚拟)。其他细节因语言而异。所有的接口属性在java中都是隐式的公共静态final,但在C++中不是。Java允许在抽象类中使用非静态属性,但C++允许在两者中使用它们。两种语言中的属性都不能是虚拟/抽象的。

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

抽象类:轮子。

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

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

通常抽象类用于某些东西的核心,但接口用于附加外围设备。

当您想为车辆创建基本类型时,应该使用抽象类,但如果您想添加一些不属于车辆基本概念的功能或属性,则应该使用接口,例如,您想添加“ToJSON()”函数。

接口具有广泛的抽象范围,而不是抽象类。您可以在传递的论证中看到这一点。请查看以下示例:

如果您使用vehicle作为参数,您可以使用它的派生类型之一(公共汽车或汽车同一类别只是车辆类别)。但当您使用IMoveable接口作为参数时,您有更多的选择。