How to work with PHP abstract?

2019-02-23 18:28发布

Why would you use such abstract? Does it speed up work or what exactly its for?

// file1.php
abstract class Search_Adapter_Abstract {
    private $ch = null;
    abstract private function __construct()
    {
    }       
    abstract public funciton __destruct() { 
      curl_close($this->ch);
    }
    abstract public function search($searchString,$offset,$count);
}

// file2.php
include("file1.php");
class abc extends Search_Adapter_Abstract
{
    // Will the curl_close now automatically be closed?

}

What is the reason of extending abstract here? Makes me confused. What can i get from it now?

3条回答
该账号已被封号
2楼-- · 2019-02-23 19:16

This isn't going to be a popular answer, but still...

abstract, interface, private and other keywords, borrowed from Java, are elements of cargo cult programming and serve no real purpose in PHP, except to make the author appear more "serious" and "professional".

Explanation: these keywords are compile-time contracts, that have no effect on how your program runs and only meant as an aid for a compiler... assuming you have one. In a compiled language, like Java or C#, you physically cannot deploy a program that violates a contract, e.g. doesn't implement an abstract method. You simply don't get it compiled. This is a Good Thing, because you can fix some kinds of bugs very quickly, without testing and debugging.

PHP, on the contrary, doesn't have a compiler, and performs all contract checks at run time. This is a Bad Thing, because you need to test and debug to find contract violations manually. Consider the following:

class Abs {
    abstract function implementMe();
}

if ($_GET['x'] == 'foo')
    include "GoodClass.php";

if ($_GET['x'] == 'bar')
    include "BadClass.php";

where "BadClass" extends "Abs", but doesn't implement "implementMe" method. This script can be deployed and will run just fine until someone calls it with "?x=bar" and then - bang! - your program suddenly crashes. To make the things worse, this will be a "fatal" error, so that you won't be even able to handle it in a reasonable way.

That is, abstract and friends are not only useless, but also quite harmful in PHP. Not only they don't help you with bug hunting, but also they are potential source of even more glitches. Stay away.

查看更多
何必那么认真
3楼-- · 2019-02-23 19:16

So you can implement different Search adapters and all of them must implement that search method. See inheritance here.
Basically what you get is that every class extending "Search_Adapter_Abstract" can be used as a Search Adapter. The behaviour changes (because the method search is implementend differently) but you guarantee the "search" method is there with that signature.

查看更多
太酷不给撩
4楼-- · 2019-02-23 19:24

You can use abstract classes to define and partially implement common tasks that an extended class should do. Since explaining it is difficult without an example, consider this:

Without abstract classes, you would have to define two basic classes with the same methods and implementation. Since OOP is all about preventing code duplication, this is quite wrong:

class Car {
  public $brand = 'mercedes';

  public function gasPerMile($weight) 
  {
    // Useless calculation, purely for illustrating
    $foo = $weight * 89 / 100;
    return $foo;
  }

  public function carSpecificFunction() 
  {
    // Only present in class Car
  }
}

class Truck {
  public $brand = 'MAN';

  public function gasPerMile($weight) 
  {
    // Useless calculation, purely for illustrating
    $foo = $weight * 89 / 100;
    return $foo;
  }

  public function truckSpecificFunction() 
  {
    // Only present in class Truck
  }
}

Now you have some common properties and methods, which are duplicated in two classes. To prevent that, we could define an abstract class from which Car and Truck are extended. This way, common functionalities are kept in one place and the extended classes will implement specific properties and methods for either the Truck or the Car.

abstract class Vehicle {
  abstract public $brand;

  public function gasPerMile($weight) 
  {
    // Useless calculation, purely for illustrating
    $foo = $weight * 89 / 100;
    return $foo;
  }
}

This way, you ensure that atleast every class that extends Vehicle has to have a brand specified and the common gasPerMile() method can be used by all extended classes.

Of course, this is a simple example, but hopefully it illustrates why abstract classes can be useful.

查看更多
登录 后发表回答