How to implement your abstract class member the clean way
What you want to do
You got an abstract class "Foo" that operates on a class member "myFoo". But you can't define "myFoo" just yet. So you have to leave "myFoo" uninitialized and rely on any developer extending your class to take care of the issue.
First naive attempt
The naive approach to the problem may leave you with something like this:
abstract class Foo {
protected $_myFoo;
public function addThree() {
return $this->_myFoo + 3;
}
}
There are a couple of problems here.
See how this code uses "myFoo" without ever initializing it?
See how there is no "abstract" member in this class?
This is because a class member (variable) simply cannot be abstract.
If another programmer extends this base-class, will he know he needs to initialize "myFoo"? No.
Care to improve?
So the first idea didn't work too well after all. Now what?
It is very tempting at this point to "solve" the problem like this:
abstract class Foo {
/**
* Needs to be initialized in sub-class
*/
protected $_myFoo;
public function addThree() {
return $this->_myFoo + 3;
}
}
This is better, but not much. Since you can't expect a programmer to ALWAYS read all comments FIRST, before implementing a sub-class. Or do you?
How to solve the problem the clean way
Alright, so there is a much better way (and actually this is what you should really do):
abstract class Foo {
abstract protected _getMyFoo();
public function addThree() {
return $this->_getMyFoo() + 3;
}
}
Why is this better?
Now you got an abstract function that will automatically trigger an error at compile-time in case you forgot to take care of "myFoo".
No matter if you ever call "addThree" or not.
Also modern IDEs will be able to give you a warning while you type.
For any extending sub-class they may tell you that the class needs to implement '_getMyFoo()' or has to be declared 'abstract'
.
Thus there is no way to forget about initializing "myFoo" ever again.
This concludes the tutorial.
(ac/tom) Diskussion