<?php
// No company just has "employees", all employees have a particular function or belong to a group.
// So, we don't want employee to be a concrete (one that can be instantiated) class. Lets create an abstract.
abstract class Employee
{
protected $employeeID='';
protected $annualSalary=NULL;
abstract protected function setEmployeeID();
abstract protected function setAnnualSalary();
public function getEmployeeID()
{
return $this->employeeID;
}
public function getAnnualSalary()
{
return $this->annualSalaryID;
}
}
//Now lets define some interfaces based on the description above
//canHackTheSystem and canTakeLongVacations are the adjectives
//they can be used to group employees in a manner that is different then just their job
interface canHackTheSystem
{
public function getSecurityClearance();
}
interface canTakeLongVacations
{
public function getHRApproval();
}
// and now, finally our classes. Notice the implements keyword to use interfaces
class Engineer extends Employee implements canHackTheSystem
{
protected function setEmployeeID()
{
//read from db, etc.
}
protected function setAnnualSalary()
{
//beg HR for a raise
}
//required by the interface 'canHackTheSystem'
public function getSecurityClearance()
{
//of course, they have all access
}
}
class Executive extends Employee implements canTakeLongVacations
{
protected function setEmployeeID()
{
//read from super-special db, etc.
}
protected function setAnnualSalary()
{
//definitely a large number
}
//required by the interface 'canTakeLongVacations'
public function getHRApproval()
{
//all those bribes and gifts paid off
}
}
//instantiate
$engineer = new Engineer;
$executive = new Executive;
//ok, with these defined and instantiated, we can do cool stuff like this
//a more applicable example might be if the object was instantiated via a Factory
//but hopefully you get the idea.
if ($executive instanceof canTakeLongVacations) {
// schedule meetings during the winter months
}
if ($engineer instanceof canHackTheSystem) {
// don't fire this person, they hold the keys to the kingdom
}
?>
So, the code above, we've defined an abstract that lets us create a partial blueprint for child classes along with shared members and methods that children don't need to define. We've also defined some interfaces that certain employee objects will implement if they are relevant. Finally, our code can reference those interface attributes (we're doing that with the instanceof keyword in this case) and make decisions based on their implementation of that interface. Pretty cool, huh? And that's just a simple example. Consider the definition of the Senior Engineer and you'll see that the sky's the limit:
class SeniorEngineer extends Engineer implements canHackTheSystem, canTakeLongVacations
{
//she can do it all
}
So, hopefully this example demostrates the basic differences. You can learn about the nuisances and best practices for both (probably makes sense for your abstracts to implement interfaces themselves, for example) from the links below.
IMO, if you're new to this concept and are not exactly sure how you will use it, you can skip the "Interface vs. Abstract" debate and just use abstract. You can use it just like interfaces (although you can only have one) and can use it for the shared code aspect as well.