4

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?

j0k
  • 22,600
  • 28
  • 79
  • 90
  • 6
    possible duplicate: http://stackoverflow.com/questions/1814821/interface-vs-abstract-class – Marek Sebera Aug 30 '11 at 12:32
  • @marek-sebera that's a good link with a good explanation. – Lars Aug 30 '11 at 12:35
  • I don't get it... Does that snippet even work?! As far as I know, abstract methods **cannot be defined** (i.e., you can write `abstract public function smth();` in abstract class and `public function smth() {}` in another class, but not `abstract public function smth() {}`), as well as abstract methods **cannot be private**, as they cannot be defined in the same class. All I see for that snippet is *Fatal error* being raised because of these errors. – binaryLV Aug 30 '11 at 13:04

3 Answers3

3

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.

Luwe
  • 3,026
  • 1
  • 20
  • 21
  • can you put in abstract class something who is automatically calls its private variable on __destruct? e.g: abstract public funciton __destruct() { curl_close($this->ch); } –  Aug 30 '11 at 13:01
  • No, private properties are not available in extended classes, so you should make them either public or protected. Furthermore, if you add the `abstract` keyword, the method can only be defined and not do anything. If you want the function to do something in the abstract class, you should omit the `abstract` keyword. – Luwe Aug 30 '11 at 13:08
2

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.

CaNNaDaRk
  • 1,302
  • 12
  • 20
  • 1
    What makes that specific for an abstract class? Aren't interfaces used for that? – hakre Aug 30 '11 at 12:40
  • With an abstract class you can also provide other implemented methods or even variables. An interface must have only abstract methods. Look at http://stackoverflow.com/questions/1814821/interface-vs-abstract-class – CaNNaDaRk Aug 30 '11 at 12:41
  • But doesn't that make the replacement of a search implementation with another *more* complicate than using a search interface? – hakre Aug 30 '11 at 12:46
  • Don't get what you mean with "complicate" and "replacement", do you mean override? Do you mean switching Search adapters within another class? In both cases i don't see such complications. To switch between two search methods just switch between two different implementations of Search_Adapter_Abstract. As it is designed right now the different between Search_Adapter_Abstract and an interface with a same signature "search" method involves only multiple inheritance. Differences are explained in the link above. – CaNNaDaRk Aug 30 '11 at 12:52
  • 2
    Well one implementation might not work with the abstract base class because of technical reasons. Then you're doomed by not using an interface but enforce a (abstract) base class. As in your answer you're making the argument that abstract classes help to keep things de-coupled, I'm just saying that interfaces better help with de-coupling. – hakre Aug 30 '11 at 12:54
  • @CaNNaDaRk: Can i have an abstract class where i can tell __destruct() { curl_close($this->ch); }. So that who ever extends my abstract without doing anything it will automatically call the __destruct? –  Aug 30 '11 at 12:55
  • @goOgle: You need to make the `__destruct()` final. Additionally ensure that you understand it right when `__destruct()` gets called. – hakre Aug 30 '11 at 12:57
2

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.

user187291
  • 53,363
  • 19
  • 95
  • 127
  • 2
    That is what we need unit, acceptance, and other tests for ;-) – zerkms Sep 23 '11 at 10:07
  • 1
    You can't be serious right, you prankster you...? That's the whole point of contracts. You must fulfill the contract or feel the pain of exceptions and errors. Contracts can enforce type, they can assure logic adheres to a standard you expect at various points throughout your application. If you don't test your application before deploying it to production, then that's on you. The fact that these checks are performed at run-time in PHP is something you have to live with and above all this has absolutely nothing to do with cargo cult programming. – userabuser Mar 29 '14 at 02:09
  • That is unpopular opinion indeed, but thank you, I'm glad I'm not alone having very similar opinion. – DeDee Mar 19 '15 at 19:39