Jump to content

Recommended Posts

No. An interface is like a blueprint.

 

For example - you can set up an interface for Shapes. In the interface, state some methods like getArea(). Then all classes that implements Shapes *must* have that method. So if someone knows that a class implements an interface, then that person knows it must have that method without searching through all the code. Of course the class can have other methods, but it must have all the ones in the interface as well.

It has its uses.

 

<?php

interface Shape {
     public function getArea();
}

class Square implements Shape {
     private $width;
     private $height;
     public function __construct($width = 0, $height = 0) {
          $this->width = intval($width);
          $this->height = intval($height);
     }
     public function getArea () {
          return $this->width * $this->height;
     }
}

class Triangle implements Shape {
     private $base;
     private $height;
     public function __construct($base = 0, $height = 0) {
          $this->width = intval($base);
          $this->height = intval($height);
     }
     public function getArea () {
          return .5 * $this->width * $this->height;
     }
}

class Drawing {
     private $shape;
     public function __construct (Shape $shape) {
          $this->shape = $shape;
     }
     public function getShapeArea () {
          return $this->shape->getArea();
     }
}

 

With an interface, coders do not have to worry about what is in the classes of Shape. They know it has the getArea() method. Now you say in the example above, it's not that great. But what if I add another method into the interface. Something like a compare method that takes a Shape.

 

<?php

interface Shape {
     public function getArea();
     public function compare (Shape $shape);
}

 

Then you know you have a compare method that only takes a Shape. It's pretty neat what you can do with a few interfaces. It definitely keeps code more predictable. It makes sense too. I created a Java animation using interfaces so I know how useful they are.

 

I don't know how well I explained it. Hopefully you got some hints of how it can be useful. If not, I'll try again next time.

The idea of an interface is to ensure that a class implements a particular interface. The interface of a class is the public methods it exposes, so in the following class:

class Foo
{
public function fooA();
public function fooB();
private function fooC();
}

 

The interface would consist of the methods fooA() and fooB().

 

So if you have these interface:

interface XMLable
{
public function getAsXml();
}
interface JSONable
{
public function getAsJson();
}

 

Then you know that if an object is an instance of XMLable then its interface is guaranteed to have the method getAsXml(). Same thing goes for JSONable, but with getAsJson() instead. There is no reason why a class couldn't have functionality for both representing itself using XML and JSON, so it can implement both interfaces if necessary. This can be checked at runtime. Example:

 

// this is within some arbitrary class
public function returnAjaxResponse(JSONable $obj)
{
echo $obj->getAsJson();
}

public function generateConfigFile(array $objects)
{
$return = "<config>\n\t<items>\n";

foreach ($objects as $object) {
	if (!$object instanceof XMLable) {
		throw new InvalidArgumentException('All objects must implement the XMLable interface.');
	}
	$return .= $object->getAsXml();
}

$return .= "\n\t</items>\n</config>\n";

return $return;
}

 

If you have this class:

class Something extends Parent implements Foo, Bar

Then it is an instance of both Something, Parent, Foo, and Bar, and instances of Something will pass instanceof checks and type hinting as seen in generateConfigFile() and returnAjaxResponse(), respectively.

 

 

An abstract class is conceptually different. It can be said to be abstract in the sense that it's incomplete, or it's a generalized version of something. You might have an abstract class that represents a wrapper around a database. Considering it contains general information that applies to all databases, but no particular database, it cannot be used individually. It could possibly have declared abstract methods that descendants need to implement. A subclass of that could be one that knows how to connect specifically to MySQL databases, or Oracle, or DB2, etc. Either way these are concrete implementations of the abstract super class, and insofar they implement the super's abstract methods, this is perfectly fine.

 

Abstract methods can be both public, private or protected, but methods declared in an interface can only be public because interfaces are just for ensuring that a given objects implements a particular interface, i.e. has defined set of public methods implemented.

 

 

Ken's example, while it does illustrate how an interface can be used, actually fails to use interfaces correctly. A square is a shape and as such, Shape should actually have been a (abstract) class. A problem people often have with understanding the differences between interfaces and abstract classes is that they seemingly allow you to do the same thing, i.e. ensuring that you have certain methods, but they are conceptually different and are used for different purposes. I hope the examples I've given illustrate the difference in usage.

I'm not sure how helpful this will be, but here's another way of looking at it.

 

Both abstract classes and interfaces help create and enforce type.  They each do it in different ways.

 

Like Daniel said, abstract classes are incomplete.  Their most common use is to be an uninstantiated base class that other classes derive from.  Here's a canned example:

abstract class Animal
{
   public function makeSound();

   public function walk()
   {
      echo "I moved 3 feet";
   }
}

class Cat extends Animal
{
   public function makeSound()
   {
      echo "Meow";
   }
}

class Dog extends Animal
{
   public function makeSound()
   {
      echo "Woof";
   }
}

 

As you can see, abstract classes can have a mix of methods that are declared, but not defined (makeSound()) and fully defined methods (walk()).  The important thing to remember is that abstract classes can't be instantiated (that is, you can't create an object of that class), so they are used as base/parent classes.

 

Interfaces, again like Ken and Daniel said, enforce their own interfaces (sounds dumb, but bear with me).  The methods in an interface are never defined - instead, any class that implements that interface must provide definitions for each interface method.

 

So, what does this have to do with type?  Look at the following example:

abstract class Collection
{
   protected $items;

   protected function push($item);
   protected function pop();
}

interface IEnumerable
{
   public function count();
   public function next();
   public function previous();
}

class Stack extends Collection implements IEnumerable { }
class Queue extends Collection implements IEnumerable { }

 

Both Stack and Queue can be considered to be an object of three distinct types:

 

Their own type (Stack or Queue)

Collection

IEnumerable

 

Daniel's example took advantage of this fact as he checked whether or not his objects were XMLable.

 

With OOP, as you get more familiar with it, you'll see that two of the more important considerations are an object's type and an object's interface.  The two often go hand-in-hand.

 

Look at the example with the animal-themed classes again.  Cat and Dog aren't entirely the same.  But, since they share the same base class, and their public interfaces are the same, they can be used interchangeably in certain instances:

class Zoo
{
   private $animals;

   public function addAnimal(Animal $animal)
   {
      $this->animals[] = $animal;
   }

   public function makeSound()
   {
      foreach($this->animals as $animal)
      {
         $animal->makeSound();
      }
   }
}

 

That Zoo could contain nothing but Dogs, nothing but Cats, or a mix of each.  But, it doesn't matter what is actually contained in the Zoo, as we can treat everything uniformly.

 

Hopefully this helps a bit.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.