Difference between revisions of "6CC001 Workshop - week 03"

From mi-linux
Jump to navigationJump to search
 
(5 intermediate revisions by the same user not shown)
Line 10: Line 10:
  
 
<pre>
 
<pre>
 +
// Preferences.php
 +
 
class Preferences
 
class Preferences
 
{
 
{
Line 26: Line 28:
 
</pre>
 
</pre>
  
Now one object could store a value...
+
Let's test our new class:
  
 
<pre>
 
<pre>
 +
// test.php
 +
 +
require_once("Preferences.php");
 +
 +
//Now one object could store a value...
 
Preferences::set("db_server", "mi-linux");
 
Preferences::set("db_server", "mi-linux");
</pre>
 
  
… that could then be retrieved by another object:
+
// ...
  
<pre>
+
// ... that could then be retrieved by another object:
 
$db_server = Preferences::get("db_server");
 
$db_server = Preferences::get("db_server");
 
echo $db_server;
 
echo $db_server;
Line 46: Line 52:
  
 
<pre>
 
<pre>
 +
// Shape.php
 +
 
abstract class Shape
 
abstract class Shape
 
{
 
{
Line 68: Line 76:
 
A first child class could be:
 
A first child class could be:
 
<pre>
 
<pre>
 +
// Rectangle.php
 +
 +
require_once("Shape.php");
 +
 
class Rectangle extends Shape
 
class Rectangle extends Shape
 
{
 
{
Line 83: Line 95:
 
Likewise, another child class could be :
 
Likewise, another child class could be :
 
<pre>
 
<pre>
 +
// Circle.php
 +
 +
require_once("Shape.php");
 +
 
class Circle extends Shape
 
class Circle extends Shape
 
{
 
{
Line 105: Line 121:
  
 
<pre>
 
<pre>
 +
//test.php
 +
 +
require_once("Rectangle.php");
 +
require_once("Circle.php");
 +
 
$rectangle = new Rectangle(50, 30);
 
$rectangle = new Rectangle(50, 30);
 
$circle = new Circle(10);
 
$circle = new Circle(10);
Line 120: Line 141:
 
A simple example:
 
A simple example:
 
<pre>
 
<pre>
 +
// FileReader.php
 +
 
class FileReader
 
class FileReader
 
{
 
{
Line 135: Line 158:
  
 
<pre>
 
<pre>
 +
// test.php
 +
 +
require_once("FileReader.php");
 +
 
try
 
try
 
{
 
{

Latest revision as of 12:22, 9 February 2012

Main Page >> Advanced Web Technologies >> Workbook >> Week 03

Static classes - An example

Global variables undermine OO programming:

  • If a class relies on a certain global variable to work, then it can not be reused in another application.
  • It also causes tight coupling: 2 parts of a system tightly bound together, so that a change in one part necessitates a change in the other part.

However using some sort of global variable mechanism can be tempting, and sometimes more efficient than getting your classes to pass information all around the system. Let’s create a simple “Preferences” class, using static properties and methods.

// Preferences.php

class Preferences
{
  private static $values = array();
  
  static function set($key, $val)
  {
    self::$values[$key] = $val;
  }
  
  static function get($key)
  {
    return self::$values[$key];
  }
}

Let's test our new class:

// test.php

require_once("Preferences.php");

//Now one object could store a value...
Preferences::set("db_server", "mi-linux");

// ...

// ... that could then be retrieved by another object:
$db_server = Preferences::get("db_server");
echo $db_server;

Abstract classes - an example

An abstract class cannot be instantiated, i.e. you cannot use the “new” operator to create objects.

An abstract class defines (and optionally partially implements) the interface for any class that might extend it (via inheritance).

// Shape.php

abstract class Shape
{
  protected $height;
  protected $width;
  
  public function __construct($height, $width)
  {
    $this->height = $height;
    $this->width = $width;
  }
  
  abstract public function CalculateSurface();
} 

This “Shape” class is telling us:

  • I am abstract, and as such cannot be used directly. I am only a rough template that other classes can build on via inheritance.
  • All my “children” classes will have $height and $width attributes, as well as a standard constructor method.
  • They must also have a CalculateSurface method, but I leave it to them to implement how that bit works.

A first child class could be:

// Rectangle.php

require_once("Shape.php");

class Rectangle extends Shape
{
  public function CalculateSurface()
  {
    return $this->height * $this->width;
  }
}

This “Rectangle” class is telling us:

  • I wish to extend the Shape class, and as such I inherits the $height and $width attributes, as well as the standard constructor method.
  • Furthermore, and as per “contract”, I provide an implementation for the CalculateSurface method.

Likewise, another child class could be :

// Circle.php

require_once("Shape.php");

class Circle extends Shape
{
  public function __construct($height)
  {
    $this->height = $height;
    $this->width = $height;  
  }
  public function CalculateSurface()
  {
    $radius = $this->height/2;
    return 3.14 * $radius * $radius;
  }
}

This “Circle” class is telling us:

  • I wish to extend the Shape class, but I choose to override the constructor method (since being a circle means my height and width are equal)
  • Furthermore, and as per “contract”, I provide an implementation for the CalculateSurface method.

You can instantiate the Circle and Rectangle classes, as they are not abstract:

//test.php

require_once("Rectangle.php");
require_once("Circle.php");

$rectangle = new Rectangle(50, 30);
$circle = new Circle(10);

print $rectangle->CalculateSurface()."<br>";
print $circle->CalculateSurface()."<br>";

Exceptions - an example

PHP 5 finally introduces exceptions!

  • Exceptions are special objects that handle unexpected results and errors.
  • The code producing the error throws an exception, and the code handling the error catches the exception.

A simple example:

// FileReader.php

class FileReader
{
  function __construct($filename)
  {
    if(!file_exists($filename))
      throw new Exception("File {$filename} doesn’t exist");
  }
}

Our “FileReader” object might detect an error (e.g. the file doesn’t exist). But it hasn’t got enough contextual information to know what to do about it. If we were to make our class more aware of its context, it would become less reusable!

So it simply throws an exception, and lets the calling code sort it out:

// test.php

require_once("FileReader.php");

try
{
  $file = new FileReader('not_there.txt');
}
catch(Exception $e)
{
  die ($e->getMessage());
}