【问题标题】:What are the advantage if i use abstract class in php? [duplicate]如果我在 php 中使用抽象类有什么好处? [复制]
【发布时间】:2011-09-16 10:10:50
【问题描述】:

可能重复:
interface vs abstract class

如果我使用有什么好处 php中的抽象类?

如果我使用抽象的目的是什么 类还是接口?

两者都只是在创造防御 没有身体的名字

【问题讨论】:

标签: php oop abstract-class


【解决方案1】:

如果我在 php 中使用抽象类有什么好处?我找不到任何好的东西。我想我可以轻松地完成所有工作而不使用抽象类?

你当然可以。但是,如果有许多对象的类型几乎相同,那么将通用功能提取到“基”类中可能会有所帮助,这意味着您不必复制该逻辑。

其实有两个原因。对我来说,第一个原因是抽象类的所有后代都具有相同的类型,并且都遵循完全相同的接口。这意味着例如 PDF 文档将具有与 docx 文档相同的界面,并且客户端代码不必关心它正在处理哪个对象。简短示例(在 PHP 中)。

<?php
abstract class Document {
    protected $author;

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

    abstract public function render( );

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

class PdfDocument extends Document {
    public function render( ) {
        // do something PDF specific here.
    }
}

class DocxDocument extends Document {
    public function render( ) {
        // do something DOCX specific here.
    }
}


class DocumentHandler {
    public function handle( Document $document ) {
        $this->log( 'Author has been read ' . $document->author( ) );
        return $document->render( );
    }
}

首先;请注意 DocumentHandler 类不知道它实际处理的 Document 类型。它甚至不在乎。这是无知的。但是,它确实知道可以调用哪些方法,因为这两种类型的 Document 之间的接口是相同的。这称为多态性,可以通过实现 Document 接口轻松实现。

第二部分是;如果每个文档都有一个作者,并且总是要求该作者,您可以将该方法复制到 PdfDocument 以及 DocxDocument,但您会复制自己。例如,如果您决定希望作者用大写字母书写,并且您将 return $this->author 更改为 ucwords( $this->author ),那么您必须多次这样做我复制了那个方法。使用抽象类,您可以定义行为,同时将类本身标记为不完整。这非常方便。

希望对您有所帮助。

【讨论】:

  • 很棒的解释,谢谢!
  • @Berry Langerak我不明白:$this->log('Author has been read'. $document->author());如何将 var 值传递给 Document 构造函数?
  • @pregmatch 这是很久以前的事了,但我会把它留给有同样问题的人。所以,当他创建一个新对象时,例如 PdfDocument 类,他会将它作为参数传递给那里例如:$author = '詹姆斯乔伊斯'; $document = new PdfDocument($author); (从那里它将传递给 Document 的类构造函数)然后类似: $DocumentHandler = new DocumentHandler();和 $DocumentHandler->handle($document);
  • @pregmatch 我添加了一个更详细的示例,说明如何在 pastebin 上使用它,以防您想测试它。这只是 Berry 的 Langerak 示例的扩展。 [链接]pastebin.com/fafiMbXL
【解决方案2】:

当您有许多具有相同方法的类时,抽象类会为您提供帮助。

例子:

abstract class Foo {
  public function foo1() {
    //Do something
  }

  public abstract class foo2();
}

class Bar extends Foo {
  public class foo2() {
    //Do something
  }
}

class Baz extends Foo {
}

会发生什么:

  • 你不能用new Foo();Foo是抽象的。
  • 您将能够使用Bar.foo1()Baz.foo1(),它们会做同样的事情。
  • 你会遇到错误,因为Baz 没有实现抽象方法foo2

有用的例子:

abstract class Shape {
  public function display() { /* ... */ }
  //...
}

class Circle extends Shape {
  //...
}

class Rectangle extends Shape {
  //...
}

//...

您希望每个班级都能够display(),但本身并没有“形状”之类的东西。

【讨论】:

    【解决方案3】:

    并非所有抽象类的方法都必须为空,可能有一些基本方法(和属性)可以使用。例如 - 你有一个电子商店,你开发了一个抽象类来导入产品。该类有一个方法将产品保存到数据库,生成产品的 url 和一个从某个地方检索产品的抽象方法(因此必须在扩展类中实现)。 接口只有空白方法,没有属性(虽然可以有常量),所以可能没有实际的逻辑,只有方法常量、方法名称及其访问修饰符。

    【讨论】:

      【解决方案4】:

      顾名思义,接口的目的是显式声明类和实例提供的数据和方法的接口,而无需立即对这些方法进行编码。经典的例子是几何形状。这样的接口可以定义一个方法来产生这种形状的区域:

      interface Shape {
          public function getArea();
      }
      

      可能有许多不同的类实现此接口,例如CircleSquare,它们将为方法getArea() 提供不同的实现。然后,您可以实现一个显示任何几何形状信息的函数:

      function displayInformation(Shape $shape) {
          echo "The area of this shape is: " . $shape->getArea();
      }
      

      您可以将任何实现了Shape 接口的对象传递给此函数,并且该接口保证存在getArea() 方法。

      当然,这些概念在类型比 PHP 更强的编程语言中可能更有用。

      【讨论】:

        猜你喜欢
        • 2010-11-16
        • 2013-06-23
        • 1970-01-01
        • 2019-08-22
        • 2010-11-06
        • 2010-12-31
        • 1970-01-01
        • 2014-01-15
        • 2019-07-16
        相关资源
        最近更新 更多