There needs to be a companion to the final
keyword in #PHP.
Background: The "final" keyword indicates that a method cannot be overridden in a child class.
Wish: There needs to be a first
keyword to prevent accidentally creating a method ancestor which might get completely bypassed because a descendant doesn't call parent::[method]
because it doesn't expect one to exist.
Either that, or a way to allow calls to parent::[method]()
even when there's no method ancestor.
...or else a way to define a method such that each generation gets called automatically -- except that takes away sequencing control, which would cause problems.
@woozle I am not sure what "first" would do
@GoatSara It would cause an error if you tried to implement the same method in a parent class.
Let's say X is a method which needs to be called in every class because it initializes things. If class B descends from class A, and class A contains X(), then B::X() needs to call parent::X() so that A::X() gets called -- but if B::X() was written before A::X() existed, and the author of A::X() forgets that B::X() exists and doesn't call parent::X(), then A::X() won't get called.
Here's how it would work.
class A {
function X() {}
}
class B extends A {
function X() {}
}
Language processor sees no problem.
class A {
function X() {} // this gives an error
}
class B extends A {
first function X() {}
}
@woozle I have trouble fully understanding but it looks like something I have never seen before
@GoatSara Do you understand the need for it, or maybe that's where I need to explain more?
@woozle I cannot really understand why there would be a need
@GoatSara Do you understand the need for being sure that A::X() gets called from B::X()?
@woozle For proper initialization?
@GoatSara That covers all of my current usage cases I think, yes.
So then the problem arises when I've got B::X(), which originally had no parent to call, and then (some time later) I go and create A::X() because I realize there's some initialization which needs to be done, and I forget that B::X() exists (or that it doesn't already call parent::X())...
...and then either I wonder why A::X() isn't getting called, or maybe I guess that this is the problem but it takes me a long time to trace down through the class structure to figure out that B::X() is the culprit.
(Note that in practical use, A and B are often separated by several layers of classes and often traits as well -- the offending X() could be in any of them.)
Is that making sense yet?
@woozle Yeah it makes a bit sense to fix some class problems