【发布时间】:2011-09-16 10:10:50
【问题描述】:
【问题讨论】:
-
是的,我明白..想结束这个问题
-
呸,在我花了十分钟写完答案之后? :(
-
@Berry,在这方面做得很好!
-
@Berry,你做得很好......谢谢你......它将永远在这里
标签: php oop abstract-class
【问题讨论】:
标签: php oop abstract-class
如果我在 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 ),那么您必须多次这样做我复制了那个方法。使用抽象类,您可以定义行为,同时将类本身标记为不完整。这非常方便。
希望对您有所帮助。
【讨论】:
当您有许多具有相同方法的类时,抽象类会为您提供帮助。
例子:
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(),但本身并没有“形状”之类的东西。
【讨论】:
并非所有抽象类的方法都必须为空,可能有一些基本方法(和属性)可以使用。例如 - 你有一个电子商店,你开发了一个抽象类来导入产品。该类有一个方法将产品保存到数据库,生成产品的 url 和一个从某个地方检索产品的抽象方法(因此必须在扩展类中实现)。 接口只有空白方法,没有属性(虽然可以有常量),所以可能没有实际的逻辑,只有方法常量、方法名称及其访问修饰符。
【讨论】:
顾名思义,接口的目的是显式声明类和实例提供的数据和方法的接口,而无需立即对这些方法进行编码。经典的例子是几何形状。这样的接口可以定义一个方法来产生这种形状的区域:
interface Shape {
public function getArea();
}
可能有许多不同的类实现此接口,例如Circle 和Square,它们将为方法getArea() 提供不同的实现。然后,您可以实现一个显示任何几何形状信息的函数:
function displayInformation(Shape $shape) {
echo "The area of this shape is: " . $shape->getArea();
}
您可以将任何实现了Shape 接口的对象传递给此函数,并且该接口保证存在getArea() 方法。
当然,这些概念在类型比 PHP 更强的编程语言中可能更有用。
【讨论】: