Wednesday, October 21, 2009

Section 6.4. Declaring a Class










6.4. Declaring a Class



To design your program or code library in an object-oriented fashion, you'll need to define your own classes, using the class keyword. A class definition includes the class name and the properties and methods of the class. Class names are case-insensitive and must conform to the rules for PHP identifiers. The class name stdClass is reserved. Here's the syntax for a class definition:



class classname [ extends baseclass ]
{
[ var $property [ = value ]; ... ]

[ function functionname (args) {
// code
}
...
]
}




6.4.1. Declaring Methods





A method is a function defined inside a class. Although PHP imposes no special restrictions, most methods act only on data within the object in which the method resides. Method names beginning with two underscores (_ _) may be used in the future by PHP (and are currently used for the object serialization methods _ _sleep( ) and _ _wakeup( ), described later in this chapter, among others), so it's recommended that you do not begin your method names with this sequence.


Within a method, the $this variable contains a reference to the object on which the method was called. For instance, if you call $rasmus->birthday( ) inside the birthday( ) method, $this holds the same value as $rasmus. Methods use the $this variable to access the properties of the current object and to call other methods on that object.


Here's a simple class definition of the Person class that shows the $this variable in action:



class Person {
var $name;

function get_name ( ) {
return $this->name;
}

function set_name ($new_name) {
$this->name = $new_name;
}
}



As you can see, the get_name( ) and set_name( ) methods use $this to access and set the $name property of the current object.


To declare a method as a static method, use the static keyword. Inside of static methods the variable $this is not defined. For example:



class HTML_Stuff {
static function start_table( ) {
echo "<table border='1'>\n";
}
static function end_table ( ) {
echo "</table>\n";
}
}
HTML_Stuff::start_table( );
// print HTML table rows and columns
HTML_Stuff::end_table( );



If you declare a method using the final keyword, subclasses cannot override that method. For example:



class Person {
var $name;

final function get_name ( ) {
return $this->name;
}
}





6.4.2. Declaring Properties





In the previous definition of the Person class, we explicitly declared the $name property. Property declarations are optional and are simply a courtesy to whoever maintains your program. It's good PHP style to declare your properties, but you can add new properties at any time.


Here's a version of the Person class that has an undeclared $name property:



class Person {
function get_name ( )
{
return $this->name; }

function set_name ($new_name) {
$this->name = $new_name;
}
}



You can assign default values to properties, but those default values must be simple constants:



var $name = 'J Doe'; // works
var $age = 0; // works
var $day = 60*60*24; // doesn't work



Using access modifiers, you can change the visibility of properties. Properties that are accessible outside the object's scope should be declared public; properties on an instance that can only be accessed by methods within the same class should be declared private. Finally, properties declared as protected can only be accessed by the object's class methods and the class methods of classes inheriting from the class. For example, you might declare a user class:



class Person {
protected $rowId = 0;
public $username = 'Anyone can see me';
private $hidden = true;
}



In addition to properties on instances of objects, PHP allows you to define static properties, which are variables on an object class, and can be accessed by referencing the property with the class name. For example:



class Person {
static $global = 23;
}
$localCopy = Person::$global;



Inside an instance of the object class, you can also refer to the static property using the self keyword, like echo self::$global;.


If a property is accessed on an object that doesn't exist, and if the _ _get( ) or _ _set( ) method is defined for the object's class, that method is given an opportunity to either retrieve a value or set the value for that property.


For example, you might declare a class that represents data pulled from a database, but you might not want to pull in large data valuessuch as BLOBsunless specifically requested. One way to implement that, of course, would be to create access methods for the property that read and write the data whenever requested. Another method might be to use these overloading methods:



class Person {
_ _get($property) {
if ($property == 'biography') {
$biography = "long text here..."; // would retrieve from database
return $biography;
}
}

_ _set($property, $value) {
if ($property == 'biography') {
// set the value in the database
}
}





6.4.3. Declaring Constants





Like global constants, assigned through the define( ) function, PHP provides a way to assign constants within a class. Like static properties, constants can be accessed directly through the class or within object methods using the self notation. Once a constant is defined, its value cannot be changed.



class PaymentMethod {
const TYPE_CREDITCARD = 0;
const TYPE_CASH = 1;
}
echo PaymentMethod::TYPE_CREDITCARD;



As with global constants, it is common practice to define class constants with uppercase identifiers.




6.4.4. Inheritance


To inherit the properties and methods from another class, use the extends keyword in the class definition, followed by the name of the base class:



class Person {
var $name, $address, $age;
}

class Employee extends Person {
var $position, $salary;
}



The Employee class contains the $position and $salary properties, as well as the $name, $address, and $age properties inherited from the Person class.


If a derived class has a property or method with the same name as one in its parent class, the property or method in the derived class takes precedence over the property or method in the parent class. Referencing the property returns the value of the property on the child, while referencing the method calls the method on the child.


To access an overridden method, use the parent::method( ) notation:



parent::birthday( ); // call parent class's birthday( ) method



A common mistake is to hardcode the name of the parent class into calls to overridden methods:



Creature::birthday( ); // when Creature is the parent class



This is a mistake because it distributes knowledge of the parent class's name all over the derived class. Using parent:: centralizes the knowledge of the parent class in the extends clause.


If a method might be subclassed and you want to ensure that you're calling it on the current class, use the self::method( ) notation:



self::birthday( ); // call this class's birthday( ) method



To check if an object is an instance of a particular class or if it implements a particular interface (see the Interfaces section which follows), you can use the instanceof operator:



if ($object instanceof Animal) {
// do something
}





6.4.5. Interfaces








Interfaces provide a way for defining contracts to which a class adheres; the interface provides method prototypes and constants, and any class which implements the interface must provide implementations for all methods in the interface. Here's the syntax for an interface definition:



interface interfacenamename
{
[ function functionname ( );
...
]
}



To declare that a class implements an interface, include the implements keyword and any number of interfaces, separated by commas:



interface Printable {
function printOutput( );
}

class ImageComponent implements Printable {
function printOutput( ) {
echo "Printing an image...";
}
}



Interfaces may inherit from other interfaces (including multiple interfaces) as long as none of the interfaces it inherits from declare methods with the same name as those declared in the child interface.




6.4.6. Abstract Methods


PHP also provides a mechanism for declaring that certain methods on the class must be implemented by subclassesthe implementation of those methods is not defined in the parent class. In these cases, you provide an abstract

method; in addition, if a class has any methods in it defined as abstract, you must also declare the class as an abstract class.



abstract class Component {
abstract function printOutput( );
}

class ImageComponent extends Component{
function printOutput( ) {
echo "Pretty picture";
}
}



Abstract classes cannot be instantiated. Also note that unlike some languages, you cannot provide a default implementation for abstract methods

.




6.4.7. Constructors


You may also provide a list of arguments following the class name when instantiating an object:



$person = new Person('Fred', 35);



These arguments are passed to the class's constructor, a special function that initializes the properties of the class.


A constructor is a function in the class called _ _construct( ). Here's a constructor for the Person class:



class Person {
function _ _construct($name, $ag'e) {
$this->name = $name;
$this->age = $age;
}
}



PHP does not provide for an automatic chain of constructors


; that is, if you instantiate an object of a derived class, only the constructor in the derived class is automatically called. For the constructor of the parent class to be called, the constructor in the derived class must explicitly call the constructor. In this example, the Employee class constructor calls the Person constructor:



class Person {
var $name, $address, $age;

function Person($name, $address, $age) {
$this->name = $name;
$this->address = $address;
$this->age = $age;
}
}

class Employee extends Person {
var $position, $salary;

function Employee($name, $address, $age, $position, $salary) {
$this->Person($name, $address, $age);
$this->position = $position;
$this->salary = $salary;
}
}





6.4.8. Destructors





Starting with PHP 5, destructor functions are available in classes. When an object is destroyed, such as when the last reference to an object is removed or the end of the script is reached, its destructor is called. PHP automatically cleans up all resources at the end of a script's execution, so their application is limited, but, for example, could be used to log the destruction of an object. The destructor is a method called _ _destructor( ):



class Building {
function _ _destructor( ) {
echo "A Building is being destroyed!";
}
}














No comments: