29

Possible Duplicate:
interface vs abstract class

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

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

Both are simply creating defenition names with out body

Community
  • 1
  • 1
Sreeraj
  • 2,690
  • 6
  • 26
  • 37

4 Answers4

72

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?

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).

<?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 does know 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.

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.

starball
  • 20,030
  • 7
  • 43
  • 238
Berry Langerak
  • 18,561
  • 4
  • 45
  • 58
  • 1
    @Berry LangerakI do not get this: $this->log( 'Author has been read ' . $document->author( ) ); How you pass var value to Document constructor? – pregmatch Apr 02 '15 at 22:08
  • 1
    @pregmatch It s a long time ago but I'll leave it here for anyone with the same question .So, when he ll create a new object of e.g PdfDocument class he will pass it there as an argument e.g : $author = 'James Joyce'; $document = new PdfDocument($author); ( from there it will pass to Document's class constructor ) then something like : $DocumentHandler = new DocumentHandler(); and $DocumentHandler->handle( $document); – skechav Jun 01 '17 at 00:05
  • @pregmatch I added a more detailed example on how to use it on pastebin in case you want to test it. It is just Berry's Langerak example extended. [link] https://pastebin.com/fafiMbXL – skechav Jun 01 '17 at 00:28
10

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();, Foo is abstract.
  • You will be able to use Bar.foo1() and Baz.foo1(), they will do the same thing.
  • You will have an error, because Baz doesn't implement the abstact method 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.

SteeveDroz
  • 6,006
  • 6
  • 33
  • 65
  • public abstract class foo2(); is it right? i think should be "abstract public function foo2();" – khaled_webdev Apr 19 '23 at 06:48
  • 1
    Both work, but [this table](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6-200-A.1) in the JVM specs gives the prefered order as `public abstract`. Yet again, your version is completely valid as long as your team agrees on the order and uses it rigorously. – SteeveDroz Apr 19 '23 at 11:47
2

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.

cypher
  • 6,822
  • 4
  • 31
  • 48
1

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 Circle and Square that would provide different implementations for the method getArea(). You could then implement a function that displays information on any geometric shape:

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

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

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

cg.
  • 3,648
  • 2
  • 26
  • 30