Page 2 of 3
Self reference - this
That’s more or less all there is to basic objects in PHP, but there are some subtle points that we need to cover to make sure that you know how everything works.
The first little problem to overcome is how does a class refer to its own methods and properties. At first you might not see the need for a class to refer to its own methods and properties - after all its seems a little strange.
In fact it is perfectly normal for a class to want to reference its own properties and methods but it isn't quite a straightforward as you might expect.
You might think that the following would work just fine:
public function add($a,$b)
But $answer in the function add isn’t the same as the $answer property defined outside of the function.
You can check this by adding the following lines:
print $mycalc -> answer;
You will see 3 and 10 printed out, demonstrating that the add method doesn’t change the answer property.
If you want a class method to use a property or another method then you have to make use of the “$this” keyword as in:
The use of $this can be thought of as specifying the current instance of the object created by the class. So if the current object is $mycalc the instruction $this->answer is converted to $mycalc->answer.
This is not only a good way to think about it as it actually corresponds to what happens. When you create an instance of a class $this gets set to point to the instances properties and methods.
The correct way to set the answer property in the Calculator class is:
public function add($a,$b)
print $mycalc -> answer;
Notice that you need to use $this everywhere you want to refer to the property of the current instance i.e. you need to change the return statement as well.
Another detail of using classes and objects is the constructor.
A constructor is simply a special method __construct which is called when an instance of the class is created. Notice that the word construct is prefixed with two underline characters.
The constructor is essentially an initialisation routine. For example:
public function __construct()
is a constructor for the Calculator class that simply sets the answer property to zero.
Constructors can have parameters.
public function __construct($a)
This constructor sets the answer property to whatever $a is at the time an instance is created. You can have as many parameters as you care to define.
This raises the question of how you specify parameters when you create a class with such a constructor. The answer is that you simply include the parameters in the line that creates the object. For example:
creates an instance of the calculator class with answer set to 4.
If you are familiar with other languages you might be wondering if it is possible to create multiple constructors in PHP each with a different signature? The answer is that constructor overloading isn't supported but you can implement the same sort of thing by manually examining the arguments passed to a constructor.
Put simply the basic idea of inheritance is to use an existing class to build a new class that is a customisation or extension of it. You can think of this as just a way to save typing or as a deep principle of program construction. In PHP programs inheritance tends to be less useful to the typical application programmer. It is of more use if you plan to build a framework for others to use.
For example, let’s suppose that the Calculator class is completely finished and working and we need a special type of calculator – perhaps a scientific calculator.
We could take all of the PHP code in the Calculator class and use it to create a new SciCalc class using nothing but copy and paste. We could then add methods and even modify existing methods “inherited” via copy and paste from Calculator.
This all works but it produces a problem for the future. Now we have two sets of more or less identical code – Calculator and the code we copied and pasted into SciCalc. Now imagine what happens when an error is found in Calculator. You will have to make any changes that fix the error in Calculator in SciCalc and vice versa. In short you now have two copies of more or less the same code to debug and maintain – not good.
Inheritance as implemented in most object-oriented languages is just an attempt to improve on copy and paste by keeping the relationship between the classes alive.
For example, in PHP you could create the SciCal class, which inherits everything Calculator has, using:
class SciCal extends Calculator
Following this, and even without writing a single line of code, SciCal has all of the methods and properties of Calculator.
That is, if you create an instance of SciCal the object can be used exactly if it was an instance of Calculator. This is just like the copy and paste replication only now if you make any changes to Calculator these are passed on immediately to SciCal without you having to do anything about it.
What do you do, however, if you want to change the way an inherited method works?
The answer is that you can override it by simply providing a new definition. For example, if the SciCal class needed to implement an addition method with worked to a higher precision say then it would simply include a new definition of the method. Any inherited methods that are redefined in this way are replaced or ‘overridden’ by their new definition.
There are a couple of minor points we need to deal with. The first is that when you override a method it isn’t destroyed – it still exists but the new method is used in place of it. PHP, and most object-oriented languages, provide a mechanism whereby you can make use of the original version of the method if you really want to.
All you have to write is
and note that you use a double colon :: in place of ->.
For example, if you have overridden add in the SciCal class which inherits from Calculator then, within the new add function, you could write:
to call the original add method. Notice that you can only use this syntax within the SciCal class.
Another subtle point is what happens to constructors when a class is inherited?
The answer depends on whether or not you provide a constructor for the new class. If you don’t provide a constructor and the base class has one then it is called automatically. That is, if the Calculator class has a constructor which takes one parameter then so does SciCalc and you have to create an instance of the class using:
even if you haven’t defined a constructor for SciCalc.
If you do define a constructor for the new class then it is used and the base class’s constructor isn’t automatically called. You can use
in the new class to explicitly call it – but you don’t have to if you don't need the initialization if provides.
In all of this discussion you need to keep in mind that you can use inheritance more than once. That is, class A can be derived from class B, which was derived from class C and so on. As said earlier however most uses of PHP don't really depend on inheritance and long inheritance chains are unusual.