Class Abstraction

PHP 5 introduces abstract classes and methods. Classes defined as
abstract may not be instantiated, and any class that
contains at least one abstract method must also be abstract. Methods
defined as abstract simply declare the method's signature - they cannot
define the implementation.

When inheriting from an abstract class, all methods marked abstract in
the parent's class declaration must be defined by the child; additionally,
these methods must be defined with the same (or a less restricted)
visibility. For example,
if the abstract method is defined as protected, the function implementation
must be defined as either protected or public, but not private. Furthermore
the signatures of the methods must match, i.e. the type hints and the number
of required arguments must be the same. For example, if the child class
defines an optional argument, where the abstract method's signature does
not, there is no conflict in the signature. This also applies to constructors
as of PHP 5.4. Before 5.4 constructor signatures could differ.

User Contributed Notes 17 notes

An Interface is like a protocol. It doesn't designate the behavior of the object; it designates how your code tells that object to act. An interface would be like the English Language: defining an interface defines how your code communicates with any object implementing that interface.

An interface is always an agreement or a promise. When a class says "I implement interface Y", it is saying "I promise to have the same public methods that any object with interface Y has".

On the other hand, an Abstract Class is like a partially built class. It is much like a document with blanks to fill in. It might be using English, but that isn't as important as the fact that some of the document is already written.

An abstract class is the foundation for another object. When a class says "I extend abstract class Y", it is saying "I use some methods or properties already defined in this other class named Y".

class X extends Y { } // this is saying that "X" is going to complete the partial class "Y".?>

You would have your class implement a particular interface if you were distributing a class to be used by other people. The interface is an agreement to have a specific set of public methods for your class.

You would have your class extend an abstract class if you (or someone else) wrote a class that already had some methods written that you want to use in your new class.

These concepts, while easy to confuse, are specifically different and distinct. For all intents and purposes, if you're the only user of any of your classes, you don't need to implement interfaces.

The documentation says: "It is not allowed to create an instance of a class that has been defined as abstract.". It only means you cannot initialize an object from an abstract class. Invoking static method of abstract class is still feasible. For example:<?phpabstract class Foo{ static function bar() { echo "test\n"; }}

Abstraction and interfaces are two very different tools. The are as close as hammers and drills. Abstract classes may have implemented methods, whereas interfaces have no implementation in themselves.

Abstract classes that declare all their methods as abstract are not interfaces with different names. One can implement multiple interfaces, but not extend multiple classes (or abstract classes).

The use of abstraction vs interfaces is problem specific and the choice is made during the design of software, not its implementation. In the same project you may as well offer an interface and a base (probably abstract) class as a reference that implements the interface. Why would you do that?

Let us assume that we want to build a system that calls different services, which in turn have actions. Normally, we could offer a method called execute that accepts the name of the action as a parameter and executes the action.

We want to make sure that classes can actually define their own ways of executing actions. So we create an interface IService that has the execute method. Well, in most of your cases, you will be copying and pasting the exact same code for execute.

We can create a reference implemention for a class named Service and implement the execute method. So, no more copying and pasting for your other classes! But what if you want to extend MySLLi?? You can implement the interface (copy-paste probably), and there you are, again with a service. Abstraction can be included in the class for initialisation code, which cannot be predefined for every class that you will write.

Hope this is not too mind-boggling and helps someone. Cheers,Alexios Tsiaparas

What does it taste like? It tastes like an apple. Now I give you a fruit.

<?php
$fruit = new Fruit();
$fruit->eat();
?>

What does that taste like??? Well, it doesn't make much sense, so you shouldn't be able to do that. This is accomplished by making the Fruit class abstract as well as the eat method inside of it.

<?php
abstract class Fruit {
private $color;

abstract public function eat();

public function setColor($c) {
$this->color = $c;
}
}
?>

Now just think about a Database class where MySQL and PostgreSQL extend it. Also, a note. An abstract class is just like an interface, but you can define methods in an abstract class whereas in an interface they are all abstract.

Please note order or positioning of the classes in your code can affect the interpreter and can cause a Fatal error: Class 'YourClass' not found if there are multiple levels of abstraction out of order. For example:<?phpabstract class horse extends animal { public function get_breed() { return "Jersey"; }}

In an Abstract Class, you can define how some methods work, where as in an Object Interface you can not.

An Object Interface is essentually nothing but a list of function names that a class must define if the class implements that interface.

An Abstract Class is essentually a prototype which hints towards what extending classes should be doing.An Abstract Class can also be thought of as a Base Class that provides some basic functionality, & also defines a built-in Object Interface that all extending classes will implement.

So, an Object Interface is really a built-in part of an Abstract Class.

a (abstract) person classa student and an employee final class, which extends person class.

simple theory is that both student and employee is an extension of the person class. the difference lies on which table the data is written on, and what other pre processing (ie mandatory field checking, type checking, etc.) needed before writing each of the classes.

codes:

<?php

abstract class person {

abstract protected function write_info();

public $LastName; public $FirstName; public $BirthDate;

public function get_Age($today=NULL){//age computation function}}

final class employee extends person{ public $EmployeeNumber; public $DateHired;

There isn't really that much of a great hurdle in understanding these things, there really isn't.

If you're defining a new class that is abstract, it means that you can make some non-abstract functions that you can use to define the general underlying behavior of that class along side abstract ones.

In interfaces, you can't do that since functions defined therewithin cannot have a body.

Abstract functions you use for classes that must define more specific behavior when "extending" your class.

So for a crude example - define by your non-abstract functions how that particular object (which may be part of a larger class hierarchy) would store and process it's data in SQL, XML, etc.

Then define abstract functions which allow someone implementing that class to specifically manipulate the data that is to be stored. Then require a format which this data must be returned in, and then in your non-abstract functions call those functions on destruction, in normal runtime, and so on.

Again, non-abstract functions, or even another class could implement the finer points of ensuring that data is in the correct format, and so on, ad infinitum.

It isn't too much of a reach to say that if you used a normal class instead of an abstract class, then there isn't much intrinsic requirement between the two classes.

Assuming that you wanted the functions to use each-others functions and you'd need to use them specifically by name, you'd have to write some code which checked to see -- lamely using function_exists() and other lamery -- if that class has the function you require for interoperability, when you could avoid all possible confusion and headaches by simply using the right tool for the job.

Ok...the docs are a bit vague when it comes to an abstract class extending another abstract class. An abstract class that extends another abstract class doesn't need to define the abstract methods from the parent class. In other words, this causes an error:

"additionally, these methods must be defined with the same (or a less restricted) visibility."

The words were not restricted in abstract class but also normal classes,the method in child Class which overwrites the parent Class can also change the the visibility of the method to same or less restricted.for example:<?phpclass ClassOne { protected static $staticone = 'nathan'; protected function changestaticone() { return self::$staticone = 'john'; }}