Accessing parent methods in PHP - php

I've got a TopLevelClass that calls AnotherClass which has functions. From inside functions, how do you access some_other_methods() for TopLevelClass?
If it were JavaScript-esque my problem would look like:
$this->parent()->parent()->do_something()
and it would be equivalent to
$this_function->AnotherClass()->LevelClass()->some_other_methods()

if you are using proper inheritance, you just need the parent keyword.
class foo {
protected function fooMethod() {}
}
class bar extends foo {
public function barMethod() {
parent::fooMethod();
// technically, you could do the same thing with $this->fooMethod()
// but this way you also know how to do it with methods that might have
// the same name as one another, such as parent::__construct()
}
}

Out the top of my head:
parent::some_other_methods();

You could make AnotherClass extend TopLevelClass with:
class AnotherClass extends TopLevelClass {
// class stuff in here
}
This would give AnotherClass access to all the methods in TopLevelClass as well as it's own (subject to Private scope status).

Related

Making a static function visible only through child class

Let's say that I have some functions in my abstract parent class. I want these to only be accessible by the children classes, so I mark the functions protected (non-static).
abstract class ParentClass
{
protected function myFunction()
{
//implementation
}
}
My problem is the following: I have a few children classes and most of them use the aforementioned protected functions. I want to create a child class though, which allows the programmer to use those functions directly.
So basically:
class ChildClass extends ParentClass
{
public static function myAwesomeFunction()
{
parent::myFunction();
}
}
This is what I want to do. I want the user to be able to call the function (can be with the same name - myFunction in the child class) in a static way from the child class, but not from the parent class (that's why I don't want to make the function public, plus since I want it to be static, marking the class abstract doesn't help with this).
To be able to call
ChildClass::myAwesomeFunction();
but not to be able to do
ParentClass:myFunction();
Is there a trick to achieve this? If not, what is the best practice to do this? Is the only way really to enumerate all the functions I want and have them call the parent's method (like I have in my example)?
You could define the abstract to be protected static and then use the self keyword in the child:
abstract class A
{
protected static function _foo() {
echo "foo\n";
}
}
class B extends A
{
public static function foo() {
self::_foo();
}
}
A::_foo(); // fatal
B::foo(); // works
Given that, I'm not really crazy about this technique, and I would generally recommend avoiding static methods -- then it simply becomes a matter of defining the abstract protected and letting the child inherit it.

How to use reflection as callback in php

I have one class
Class Mainclass{}
And another class which is
Class Childclass extends Mainclass{}
Now i want to write callback in Mainclass which check if child class found with method, merge value and return?
How can i achieve using reflection?
One easy way would be to create an interface containing that method
interface XYZ
{
public function myMethod();
}
And make your child class implement it
class Childclass extends Mainclass implements XYZ
{
public function myMethod()
{
//actual implementation
}
}
Afterwards, your main class can easily check if it is implementing that interface:
class Mainclass
{
public function whatever()
{
if ($this instanceof XYZ)
{
$this->myMethod();
}
}
}
Now, I'm fairly sure it would work but I really think this is bad design: a parent class should never depend on the implementation of its child classes. However since I don't know the context in which you're working, I'll leave this here and hope it helps you anyway.

PHP Class Extensions

I was just wondering if the next situation could be possible or not, I've read the PHP Manual documentation, but I would like another perspective because it's not so clear for me.
So I have for example one class:
class SomeClass {
public function someFunction() {
...
}
}
And an extension of it:
class Extension extends SomeClass {
public function someOtherFunction() {
...
}
}
My question is, could I be able to use the public functions inside the classes on both ways, the main class's function inside the extended function and the other way around?
And would I be doing that how?
You can use both functions from class Extension, but only someFunction() from class SomeClass.
Extension does not change the original class, it just incorporates it into a new one.
You can use the public and protectedfunctions of your parent in the extended (child) class:
class Extension extends SomeClass
{
public function someOtherFunction() {
$foo = $this->someFunction(); // from parent class
return $foo;
}
}
When class "Extension" is created, its basically a copy of "SomeClass" which you can modify in the way as you can add new functions or overwrite those of the parent class.
The parent does not know about the Extension (it can be extended multiple times, eg "JSONRequest extends Request", "XMLRequest extends Request"). Calling extended functions from within the parent makes no sense, since the parent class can never know which childs function it should call in such a situation. This type of Inheritance is one of the basic concepts of OOP and clear interfaces.
In other words, no it will never work the other way round. And it should not.

Abstract private functions

The following code will have PHP unhappy that customMethod() is private. Why is this the case? Is visibility determined by where something is declared rather than defined?
If I wanted to make customMethod only visible to boilerplate code in the Template class and prevent it from being overriden, would I just alternatively make it protected and final?
Template.php:
abstract class Template() {
abstract private function customMethod();
public function commonMethod() {
$this->customMethod();
}
}
CustomA.php:
class CustomA extends Template {
private function customMethod() {
blah...
}
}
Main.php
...
$object = new CustomA();
$object->commonMethod();
..
Abstract methods cannot be private, because by definition they must be implemented by a derived class. If you don't want it to be public, it needs to be protected, which means that it can be seen by derived classes, but nobody else.
The PHP manual on abstract classes shows you examples of using protected in this way.
If you fear that customMethod will be called outside of the CustomA class you can make the CustomA class final.
abstract class Template{
abstract protected function customMethod();
public function commonMethod() {
$this->customMethod();
}
}
final class CustomA extends Template {
protected function customMethod() {
}
}
Abstract methods are public or protected. This is a must.
Nothing in PHP that is private in a child class is visible to a parent class. Nothing that is private in a parent class is visible to a child class.
Remember, visibility must flow between the child class up to the parent class when using abstract methods in PHP. Using the visibility private in this scenario with PHP would completely encapsulate CustomA::customMethod inside of CustomA. Your only options are public or protected visibility.
Since you cannot make an instance of the abstract class Template, privacy from client-code is maintained. If you use the final keyword to prevent future classes from extending CustomA, you have a solution. However, if you must extend CustomA, you will have to live with how PHP operates for the time being.

Calling a child object in the parent object

I want to know if I can create a child object in a parent object an use it...
I mean is it posible?
Is it a good idea?
What do I have to care if I do so?
I am using the child classes on their own and i want to use them in a private function of the parent class as well.
thanks
here some source to imagine what I am meaning:
class A{
private $child_class1;
private $child_class2;
private function somefunction(){
$this->child_class1 = new B();
$this->child_class1->do_something();
$this->child_class2 = new C();
$this->child_class2->do_something();
}
}
class B extends A{
public function do_something(){
...
}
}
class C extends A{
public function do_something(){
...
}
}
You could use abstract methods to delegate certain actions to derived classes:
class A {
public function __construct() {
$this->do_something();
}
protected abstract function do_something();
}
class B extends A {
protected function do_something() {
// ...
}
}
It is not certainly a good idea to do so. It depends on what you want to achieve, and why. Creating derived classes in the parents constructor (like your previous example stated) is impossible. The language might allow it, but it will lead to an endless loop of instantiation. You will definitely need to explain why you are doing this. Otherwise nobody will be able to help you sufficiently.
This seems to be like a bad idea IMHO - it's going to require high maintenance and you are creating some tight couplings between classes.
i would recommend creating an abstract function in the parent that each of the children will implement with it's own logic.
[EDIT] since you are trying to iterate over all child objects i would recommend to create a base class that handles all the logic that needs to be implemented to all children, and override it in each of the child classes that need additional logic, and call the parent function inside it.
I think the big question should be why you would want it. I cannot come up with a solid design that would have a class extending something (the default example could be furniture, so for instance GardenChair extending Chair) be available in the parent class.
The whole idea is that it should be the other way around.
If you want to call the 'do_something', you should make an instance of the child, and let it call itself. If you need to enforce the do_something, try it like this:
public abstract class A{
public abstract funcion do_something();
public function __constructor(){
$this->do_something();
}
}
public class B extends A{
public funcion do_something(){
...
}
}
public class C extends A{
public funcion do_something(){
...
}
}

Categories