Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-如果抽象类中的所有方法都是抽象的,那么接口和抽象类之间的区别是什么_Php_Oop_Interface_Abstract Class - Fatal编程技术网

PHP-如果抽象类中的所有方法都是抽象的,那么接口和抽象类之间的区别是什么

PHP-如果抽象类中的所有方法都是抽象的,那么接口和抽象类之间的区别是什么,php,oop,interface,abstract-class,Php,Oop,Interface,Abstract Class,抽象类可能有也可能没有抽象方法,但接口只有未实现的方法。那么,如果我的抽象类的所有方法都标记为抽象,那么使用接口的区别和优势是什么呢 如果一个抽象类的所有方法都定义为抽象,那么您必须在任何子类中定义它的主体,并且它显示与接口类似的行为 好处: 使用接口而不是抽象类,您可以实现多个接口,而使用抽象类一次只能扩展一个类 编辑 我发现的另一个区别是抽象类可以有构造函数,而接口不能有 REF:抽象类允许“部分实现”(参见模板方法模式),但在这种情况下,如果所有方法都是抽象的,您就看不到这一好处。您可以做

抽象类可能有也可能没有抽象方法,但接口只有未实现的方法。那么,如果我的抽象类的所有方法都标记为抽象,那么使用接口的区别和优势是什么呢

如果一个
抽象类
的所有方法都定义为
抽象
,那么您必须在任何子类中定义它的主体,并且它显示与
接口
类似的行为

好处:

使用
接口
而不是
抽象
类,您可以
实现
多个
接口
,而使用
抽象
类一次只能扩展
一个

编辑

我发现的另一个区别是
抽象
类可以有
构造函数
,而
接口
不能有


REF:

抽象类允许“部分实现”(参见模板方法模式),但在这种情况下,如果所有方法都是抽象的,您就看不到这一好处。您可以做的另一件事是包括字段,而不仅仅限于方法

记住,“抽象方法”和由接口定义的契约在概念上是有区别的。抽象方法必须由通过继承实现完成的子类重写。任何多态调用(向下投射)都需要每个类一个超类,否则会遇到菱形继承问题。这种基于继承的树结构是面向对象设计的典型

相反,接口提供了要履行的合同的签名。只要保留签名,就可以满足许多接口的需求,因为不存在返回类层次结构以查找其他实现的问题。接口并不真正依赖多态性来实现这一点,它是基于契约的


另一点值得注意的是,您可能有“受保护”的抽象方法,在接口中执行此类操作是没有意义的(实际上这样做是非法的)。

接口和抽象 巨大的API中包含大量的类,这些类遵循一种经过深思熟虑的灵活结构,可用于未来的编码,从而显示出真正的使用能力。不管它是否会发生——你永远不知道代码是否会被扩展。接口仅用于语义原因。想象一下,您扩展了一个不推荐使用的API版本,并负责编辑/更改/实现/更新/改进/扩展/修改代码以使其保持最新,不管原因是什么。如果你不向前想,你最终会感到沮丧

小API可以在没有接口的情况下生成,这也是大多数人认为接口是不必要的地方。但一旦它们变大,它们就失去了灵活性。它们为您提供了一个类合同,提醒您需要什么,并保持概述。接口必须有公共方法,如果您有受保护的或私有的方法,只需在实现接口的类的公共方法中返回它们即可

正如您已经解释过的,接口需要实现特定的方法,抽象类不需要,因为您很可能会扩展它们。方法可以重新定义,抽象方法必须在子类中定义。接口中提到的方法只告诉您,与接口有约定的类必须定义这些方法。它可能是多个接口,您不会像处理抽象类那样从它们继承

这样想
它的逻辑是预测你计划建设的未来。无论是建筑、基础设施还是工厂的大规模生产。就像在文件夹中对书签、书籍、图像等项目进行排序一样。因为你知道,如果你不进行排序,找到一个特定的图像需要更长的时间。抽象和接口的语义目的是相似的,特别是在大型API中

  • 一个界面展现了一系列可能性和需求。
  • 抽象保留与派生上下文相关的概念信息。
我将向您展示一个典型的API开头结构,其中包含简化的内容,其中接口和抽象类具有用于将来扩展的实际使用点

/* Considering, this project will be widely expanded up to huge complexity. 
   This is a flexible base structure, for developers working in team. Imagine 
   there could be lots more variation of styles for certain purposes. */


// OOP STRUCT
// You might want to define multiple interfaces to separate the project
interface iString {
    // These methods MUST be defined or else the developer receives an error
    public function getContent();
    public function description($desc);
}

/* Devs might want to add an additional method later on. 
   Traits are useful for quick use. (optional) */

trait desc {

    private $desc;

    public function description($desc) {
        return $this->desc;
    }
}


/* This is the base class for the content which requires a declaration 
   of methods being described in the interface */

class contents implements iString {

    use desc; // use the method defined in a trait
    private $str;

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

    public function getContent() {
        return $this->str;
    }
}


/* Or devs often consider abstract classes as the real base of the whole project/app.
   Abstract classes allow the use of methods that can be modified/declared for further use in derived classes.
   Interfaces can't do that */

abstract class stylize {

    private $str;

    // This typehint below makes sure that this value is assigned on interface
    public function __construct(iString $str) { 
        $this->str = $str;
    }

    public function style() {
        return $this->str->getContent();
    }

    abstract public function getContent();
}


// EXTENDED CLASSES 
class bold extends stylize {
    // Extended classes have to define abstract methods inherited from an abstract class. Non-abstract methods are not needed.
    public function getContent() {
        return "<strong>".parent::style()."</strong>";
    }
}

class underline extends stylize {

    public function getContent() {
        return "<u>".parent::style()."</u>";
    }
}

class upperCase extends stylize {

    public function getContent() {
        return strtoupper(parent::style());
    }
}


// PROCEDUAL OUTPUT

// A tiny shortcut
$e = function($desc,$str) { echo $desc.": ".$str->getContent()."<br>"; };

// Content being used
$content = new contents('Hello World.');
$e("Normal",$content);

// Content being styled
$bold = new bold($content);
$underline = new underline($content);
$upper = new upperCase($content);

// Renders content with styles        
$e("Bold",$bold);
$e("Underline",$underline);
$e("Uppercase",$upper);
/*考虑到这一点,该项目将被广泛扩展到巨大的复杂性。
这是一个灵活的基本结构,适用于团队中的开发人员。想象
出于某些目的,可能会有更多不同的风格*/
//面向对象结构
//您可能需要定义多个接口来分隔项目
接口iString{
//必须定义这些方法,否则开发人员将收到错误
公共函数getContent();
公共功能描述($desc);
}
/*开发人员可能希望以后添加一个额外的方法。
特性对于快速使用很有用。(可选)*/
性状描述{
私人$desc;
公共功能说明($desc){
返回$this->desc;
}
}
/*这是需要声明的内容的基类
接口中描述的方法的列表*/
类内容实现iString{
use desc;//使用trait中定义的方法
私人$str;
公共函数构造($str){
$this->str=$str;
}
公共函数getContent(){
返回$this->str;
}
}
/*或DEVs经常将抽象类视为整个项目/应用程序的真正基础。
抽象类允许使用可以修改/声明的方法,以便在派生类中进一步使用。
接口不能这样做*/
抽象类样式化{
私人$str;
//下面的这个类型提示确保在接口上分配了这个值
公共功能结构(iS)
Vehicles (abstract class)
-> Ferrari (extended class)
-> Truck (extended class)

both have wheels (property)
both must be able to drive (method)

they perform a 1mile match race on a street (abstract method)

one is a slowpoke (extended property)
one is red one is blue (extended property)

and later a 3rd one comes and its a train (extended class)

who's going to win (some method)

Instantiate all vehicles and maintain privileges over interface and 
abstraction.
...something like this...