Question edited to better reflect my needs.
Take the following example:
class Base
{
public $Text = null;
public function __construct()
{
$this->Text = new Base_Text();
}
}
class Base_Text extends Base
{
public $Is = null;
public function __construct()
{
$this->Is = new Base_Text_Is();
}
public function CammelCase($string)
{
return trim(str_replace(' ', '', ucwords($string)));
}
}
class Base_Text_Is extends Base_Text
{
public function CammelCase($string)
{
return ($string === $this->CammelCase($string)); // doesn't work
}
}
How can I fix the Base_Text_Is::CammelCase()
method without calling the Base_Text class statically (not using parent::
or Base_Text::
)?
The only solution I came up with for this kind of situations is to create a singleton function like this:
function Base()
{
static $instance = null;
if (is_null($instance) === true)
{
$instance = new Base();
}
return $instance;
}
And change the Base_Text_Is::CammelCase()
method to this:
return ($string === Base()->Text->CammelCase($string));
And in order to avoid creating two object instances of the Base class, instead of doing:
$base = new Base();
$base->Text->Is->CammelCase('MethodOverloading'); // true
I just do:
Base()->Text->Is->CammelCase('MethodOverloading'); // true
Is this a good practice? Are there any other solutions?
If you override a parent method in its child, child objects will always use the overridden version. But; you can use the keyword super to call the parent method, inside the body of the child method.
Use of super with methods This is used when we want to call the parent class method. So whenever a parent and child class have the same-named methods then to resolve ambiguity we use the super keyword.
super() can be used to invoke immediate parent class constructor.
Child classes inherit accessible fields and methods from their parent classes and other ancestors. They never inherit constructors, however. Instead, child classes declare their own constructors. Furthermore, they can declare their own fields and methods to differentiate them from their parents.
The heart of your question lies here:
How can Son::B() call the Dad::A() method non-statically (without using parent or Dad)?
The answer is simply, it can't. You overrode Dad::A()
with Son::A()
. The only concept of A()
that the Son object now has is it's own A()
. You would have to call the parent method statically, or on an altogether different Dad
object instance.
The bottom line is, if you want to call the parent A()
method, why are you bothering to override it in the first place?
Your structure doesn't make any sense either. Why would you want a call to $dad->A()
pass it to $dad->son->A()
, which in turn would call $dad->son->B()
, which would then, from what you're asking, call $dad->A()
again? That's an infinite loop.
Your singleton approach doesn't seem to offer any real advantage other than making sure you don't instantiate more than one dad object, but the fact is you're still instantiating an entirely separate object to perform logic that sounds like it should be inside the class and not outside.
Without seeing actual logic and what you're trying to accomplish, it's hard to know what to recommend to avoid this circular reliance. However, I think you might want to analyze what you're trying to do with these methods and perhaps redesign how the inheritance is working.
EDIT
I think you've got way too much inheritance going on. There is no reason you should be doing this:
$base = new Base();
$base->Text->Is->CammelCase('MethodOverloading'); // true
If all the functionality is in the child classes, you shouldn't be instantiating the Base
class. It should be something like this:
$text = new Text();
$text->isCamelCase('someString');
Your code can be greatly simplified, with all the circular parent/child instantiations removed and the specific functionality pushed down to the child classes:
class Base
{
//don't put anything related to child classes here,
//unless it is going to provide specific functionality
}
class Text extends Base
{
public function CamelCase($string)
{
return trim(str_replace(' ', '', ucwords($string)));
}
public function isCamelCase($string)
{
return ($string === $this->CamelCase($string));
}
}
I don't think there is a way to call a parent method from the child with out calling it statically or using parent::
. I may be misunderstanding the question though. Creating an instance of Son() doesn't create two objects. Son extends Dad but its still one object.
If you're going to call Dad() with a Singleton within Son then why extend it from Son?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With