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


当前回答

要点是:

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

其他回答

可以在此处找到解释:http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

抽象类是一个仅部分由程序员它可能包含一个或多个抽象方法。抽象方法只是一个函数定义用于告诉程序员方法必须在子级中实现班接口类似于抽象班实际上,接口占据了与类和抽象名称空间相同类。因此,您不能定义具有相同名称的接口作为一个班级。接口是一个完整的抽象类;没有一种方法实现,而不是类从中派生出来,据说实现该接口。

无论如何,我觉得这个接口的解释有些混乱。更常见的定义是:接口定义实现类必须履行的契约。接口定义由公共成员的签名组成,没有任何实现代码。

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

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

}

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

在实用性方面(JAVA),抽象类和接口之间的主要区别是抽象类可以保存状态。除了保持状态,我们还可以使用Interface实现其余操作。

我想再加一个有意义的区别。例如,您有一个包含数千行代码的框架。现在,如果您想使用方法enhanceUI()在整个代码中添加新特性,那么最好在抽象类中添加该方法,而不是在接口中添加。因为,如果在接口中添加此方法,那么应该在所有已实现的类中实现它,但如果在抽象类中添加方法则不是这样。

相似之处这两种方法都强制类扩展或实现它们来重写基方法。

差异

一个类可以实现多个接口。一个类只能从一个抽象类扩展。接口中声明的字段必须是静态的和最终的,因为从此类实现创建的所有对象共享相同的值。在抽象类中,字段可以被命名而不被分配。子类可以覆盖它们。

用例

抽象类用于密切相关或具有几乎相同功能和行为的子类中。接口用于不相关的类,因为它只是一个没有实现的契约,所以您希望强制执行某个事情或行为。