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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6373224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:10:06  来源:igfitidea点击:

What are the advantage if i use abstract class in php?

phpoopabstract-class

提问by Sreeraj

Possible Duplicate:
interface vs abstract class

可能的重复:
接口与抽象类

What are the advantage if i use abstract class in php?

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

What is the aim if i use abstract class or interfaces?

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

Both are simply creating defenition names with out body

两者都只是在创建没有身体的防御名称

回答by Berry Langerak

What are the advantage if i use abstract class in php? i cant find anything good on that. I think i can easily do all work with out using the abstract class?

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

You could, naturally. However, if there are many objects that are of pretty much the same type, it might help to extract common functionality out into a "base" class, which means you don't have to duplicate that logic.

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

There are actually two reasons though. The first reason, for me, would be that all descendants of your abstract class have the same type, and both adhere to the exact same interface. That means that a PDF document for example will have the same interface as a docx document, and the client code doesn't have to care which object it's handling. Short example (in PHP).

但实际上有两个原因。对我来说,第一个原因是抽象类的所有后代都具有相同的 type,并且都遵循完全相同的接口。这意味着,例如,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( );
    }
}

First of all; mind the fact that the DocumentHandler class has no knowledge of which type of Document it's actually handling. It doesn't even care. It's ignorant. However, it doesknow which methods can be called upon, because the interface between the two types of Documents are the same. This is called polymorphism, and could just as easily be achieved with the implementation of a Document interface.

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

The second part is; if each and every document has an author, and that author is always requested, you could copy the method over to the PdfDocument as well as the DocxDocument, but you'd be duplicating yourself. For instance, if you decide that you want the author to written with capitals, and you'd change return $this->author to ucwords( $this->author ), you'd have to do it as many times as you've copied that method. Using an abstract class, you can define behaviour, while marking the class itself as incomplete. This comes in very handy.

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

Hope that helps.

希望有帮助。

回答by SteeveDroz

Abstract classes help you when you have many classes that have the same methods.

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

Example:

例子:

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 {
}

What will happen:

会发生什么:

  • You can't use new Foo();, Foois abstract.
  • You will be able to use Bar.foo1()and Baz.foo1(), they will do the same thing.
  • You will have an error, because Bazdoesn't implement the abstact method foo2.
  • 你不能用new Foo();Foo是抽象的。
  • 您将能够使用Bar.foo1()Baz.foo1(),他们会做同样的事情。
  • 你会出错,因为Baz没有实现 abstact 方法foo2

Example where it is usefull:

有用的示例:

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

class Circle extends Shape {
  //...
}

class Rectangle extends Shape {
  //...
}

//...

You want every class to be able to display(), but there is no such thing as "Shape" by itself.

你希望每个班级都能够display(),但没有“形状”这样的东西本身。

回答by cypher

Not all of the abstract class' methods must be empty, there may be some basic methods (and properties) to work with. For example - you have and e-shop and you develop an abstract class to import products. The class has a metod to save products to db, to generate product's url and an abstract method to retrieve products from somewhere (which therefore has to be implemented in the extended class). Interface only has blank methods and no properties (can have constants though), so tere may be no actual logic, just method constants, method names and their access modifiers.

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

回答by cg.

As the name suggests, the purpose of an interface is to explicitly declare the interface to data and methods provided by a class and the instances, without the need to code those methods right away. The classic example is that of geometric shapes. Such an interface could define a method that produces the area of such a shape:

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

interface Shape {
    public function getArea();
}

There could be a number of different classes implementing this interface like Circleand Squarethat would provide different implementations for the method getArea(). You could then implement a function that displays information on any geometric shape:

可能有许多不同的类实现了这个接口CircleSquare并且会为方法提供不同的实现getArea()。然后,您可以实现一个显示任何几何形状信息的函数:

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

You could pass any object implemented the Shapeinterface to this function, and the interface guarantees that the getArea()method is present.

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

Of course, these concepts might be more useful in programming languages that are more strongly typed than PHP.

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