The Final Keyword
Moderator: General Moderators
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
The Final Keyword
As many of you will no doubt know I am writing a form management framework/package. Throughout writing it I've been watching of opportunities to use the 'final' keyword thinking that would some how improve my code. There have been opportunities where I have thought, yes final might work there but do I really want to impose that limitation? So far I have not used it at all, ever. I found plenty of use for abstract and I'm now quite an abstract fan but despite that final still doesn't seem to be doing it for me.
Does anybody use final and if so where?
and does it really improve things, what problem is it realistically addressing?
Does anybody use final and if so where?
and does it really improve things, what problem is it realistically addressing?
- feyd
- Neighborhood Spidermoddy
- Posts: 31559
- Joined: Mon Mar 29, 2004 3:24 pm
- Location: Bothell, Washington, USA
I use it in few places, but important ones. They are used on four methods of my Object class. Why? Because I don't want anyone who is creating derivatives of this class to overwrite these functions. They, quite literally, make the class an Object. My Objects are controls of some fashion placed in the client be they visible or not.
Code: Select all
/**
* <summary>
* This magic method retrieves the data found in a property of the object.
* <param name="Name">The property name to retrieve.</param>
* <exception ref="DNAUnknownProperty">If no method nor property
* exists to set this variable, this exception will be thrown.</exception>
* </summary>
*/
final private function __get($aName)
{
if (method_exists($this, 'get' . $aName))
{
return call_user_func(array($this, 'get' . $aName));
}
elseif ($this->_propertyMap->exists($aName))
{
return $this->_propertyMap->$aName;
}
else
{
throw new DNAUnknownProperty();
}
}
/**
* <summary>
* This magic method sets the data found in a property of the object.
* <param name="Name">The property name to set.</param>
* <param name="Value">The value to store in the property.</param>
* <exception ref="DNAUnknownProperty">If no method nor property
* exists to set this variable, this exception will be thrown.</exception>
* </summary>
*/
final private function __set($aName, $aValue)
{
if (method_exists($this, 'set' . $aName))
{
return call_user_func(array($this, 'set' . $aName), $aValue);
}
elseif ($this->_propertyMap->exists($aName))
{
return $this->_propertyMap->$aName = $aValue;
}
else
{
throw new DNAUnknownProperty();
}
}
/**
* <summary>
* Add a property to the object.
* <param name="Name">The name of the property to add</param>
* <param name="Permissions">The permissions this property will be available
* to the object and associated objects. The default value is
* DNAPermissions::STANDARD_READONLY.</param>
* <remarks>Any other arguments passed to this function will be
* passed to the property during creation.</remarks>
* <returns>Boolean; Success or failure of the addition.</returns>
* </summary>
*/
final protected function addProperty($aName, $aPermissions = DNAPermissions::STANDARD_READONLY)
{
return call_user_func_array(array($this->_propertyMap, 'addProperty'), func_get_args());
}
/**
* <summary>
* Remove a property from the object.
* <param name="Name">The name of the property you wish to remove.</param>
* <remarks>This should only be called during destruction of the
* object.</remarks>
* <returns>Boolean; Success or failure of the removal.</returns>
* </summary>
*/
final protected function removeProperty($aName)
{
return call_user_func(array($this->_propertyMap, 'removeProperty'), $aName);
}- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
Re: The Final Keyword
I don't use final and I don't use private. I don't need any protection from my children.ole wrote: Does anybody use final and if so where?
and does it really improve things, what problem is it realistically addressing?
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: The Final Keyword
Watching? I use plain old objects, the plain old way until something forces me to do otherwise -- which is rare. I haven't gotten very close to any need for final or private, but never say never. The interesting thing about keywords like final and private is that they have nothing to do with design and are ultimately only design limiters. I find the most interesting design ideas are the ones where I never imagined I would need to do that.ole wrote:Throughout writing it I've been watching of opportunities to use the 'final' keyword thinking that would some how improve my code.
(#10850)
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
They help to make your design more robust and identity where things can be extended and where they cannot.The interesting thing about keywords like final and private is that they have nothing to do with design and are ultimately only design limiters.
Do you have any examples you could share?I find the most interesting design ideas are the ones where I never imagined I would need to do
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
I agree that they do those things, but those things are design limiters none the less.ole wrote:They help to make your design more robust and identity where things can be extended and where they cannot.
- Composition over inheritanceole wrote:Do you have any examples you could share?
- Front Controller
- MVC
- Doman Model
- Dependency Injection
- Test driven design
- Tell, don't ask
- ...............
(#10850)
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
private variables are important if you want to enforce an API and keeping the API safe from internal changes such that backward compatiability is maintained. If a child class wish to interrogate the private data, a protected accessor may be considered with care.
Of course, some will argue that enforcing a public API may not be feasible in an agile enviornment. An API set in stone needs to be considered and designed with great care. The final keyword is used very very rarely.
Of course, some will argue that enforcing a public API may not be feasible in an agile enviornment. An API set in stone needs to be considered and designed with great care. The final keyword is used very very rarely.
That's exactly it. Properly scoping your variables is a huge part of OOP.wei wrote:private variables are important if you want to enforce an API and keeping the API safe from internal changes such that backward compatiability is maintained. If a child class wish to interrogate the private data, a protected accessor may be considered with care.
Code: Select all
/* Prevent cloning of the instance */
private final function __clone(){}- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
That doesn't prevent it. That just provides no additional clone behaviour and it has to be public anyway
This prevents it:Good point though.
This prevents it:
Code: Select all
final public function __clone() {
throw new Exception('Cloning prohibited');
}Well it does in fact prevent it, since it is a final private function. This means that even extending classes cannot call the __clone function. PHP will throw an error of it's own if you try. The __clone function does not need to be public.ole wrote:That doesn't prevent it. That just provides no additional clone behaviour and it has to be public anyway
This prevents it:Good point though.Code: Select all
final public function __clone() { throw new Exception('Cloning prohibited'); }