Re: Why i believe we need final
| From: | (Marcus Börger) | Date: | Mon, 27 Jan 2003 21:04:07 +0000 |
| Subject: | Re: Why i believe we need final | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-93725@lists.php.net to get a copy of this message | ||
At 15:52 27.01.2003, Stanislav Malyshev wrote:
MB>> Consider you defined a container (list, vector what ever) and want MB>> to derive from it. Then there is *really*no* need to override methods MB>> like "insert" or "remove". You may want to have additional things like MB>> "insert_if" or whatever. But for the container part "insert" must stay as MB>> it is and that requires static binding. Well, if there is *really no need*, why one would override it? Obviously, if one overrides it, there's a need? I don't see why container writer should care if anyone overrides the method. Could you bring a real example where one needs non-overridable methods? Only thing I can think of are various Java security classes (like class loaders, etc.) which if you succeed to override various checking hooks may lead to trouble. But we don't have such things in PHP... For example, what if I want to create "secure container", where insert can be done only after you called password() function for the container with right password? Your 'finalized' container would not allow me to do it.Sure it cannot because insert cannot. The problem and the error you did above is that you split an operation into two. Your real operation is insert_with_password and that is different from insert. Again insert is an invariant function for the container. But now you should have a container as a member and not as a base class. Maybe it is now a good thing to have a generalised container interface and declare insert in the container implementations final. Highly specialised containers would then inheritd the interface and use a member of a less specialised container: class container_interface {
abstract function insert();
abstract function delete();
abstract function get();
}
class fifo extends container_interface {
final function insert($elem) { ... }
final function delete($elem) { ... }
final function get() { ... return ... }
}
class secure_container extends container_interface {
private $m_fifo;
function __construct()
{
$this->m_fifo = new fifo();
}
function insert($elem, $user, $passwd)
{
// check password match or emit error
$m_fifo->insert($elem);
}
...}
MB>> And here comes "final" as it allows to emulate static binding with MB>> dynamic binding. If you declare a function "final" it is invariant MB>> against inhertance starting from that point in the inhertance tree. In Could you explain what is "invariant against inhertance"? What should happen if I define function with the same name in derived class - is this a compile error?a) invariant = invariant, the meaning is described in the above and former mail (- it's about oo programming techniques (oh i remeber i wrote that in last mail already)). Again invariant against inheritance means that you have a function that is not to be overloaded since the operation is not modified by inheritance. A general container has an abstract insert operation or in full it has an abstract interface which is outlined by a collection of abstract functions. A concrete container consists of something that uses the inherited abstract interface to implement a specific container (list, array, stack, fifo, ...). A class that is derived from a concrete container may in some container implementations have final functions. For example whatever inherits a fifo must insert elements at the top and get elements from the top. And here it is of no importance what you store in the derived classes. If you have another insert implementation in a class than you missused inheritance. If the operation is different than your derived class is no for example no longer a fifo. Instead it uses a fifo. Back to oo design there is a very important rule: "is a" = (public) inheritance differs from "has a" = member (or something we do not have in php). Remeber one of our earlier discussions: I liked information hiding but it was diclined because it conflicts "is a". So in other words you insisted on pure inheritance. Now i just described one step beyond. b) What should happen? - In java you cannot redeclare a final function. - In C++ a function is an invariant if it is *not* declare virtual. Here you can redeclare it at will (but hopefully you know what that means and avoid it). Since we cannot have non virtual functions and discussing final here i am (obviously) in favor of the java solution (in real life the above is one of the few points i dislike in c++). regards marcus -- ---------------------------------------------------------------------- Marcus Börger - Looking for all sorts of freelance work - just ask... Did i help you? Consider a gift: http://www.amazon.de/exec/obidos/wishlist/ho722v0rg1u0 ----------------------------------------------------------------------