Making a static function visible only through child class - php

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.

Related

How to implement common method with custom child parameters in PHP abstract class?

I have an abstract PHP class called 'Car'.
abstract class Car
{
// Extending class must define this method
abstract protected function getBrand();
abstract protected function getCars();
// Common methods
public function printBrand() {
print $this->getBrand() . PHP_EOL;
}
public function printUrl() {
print $this->getUrl() . PHP_EOL;
}
}
This abstract class implements a function getCars(), but this function has basically the same content for each child but with different variables. As there are a couple dozen of children, this method getCars() gets redundant. Some children may also need to override the getCars() function.
Should I just copy the getCars() code to the abstract class and replace the variables with $this->getVar()? Or is this not good practice? Thanks in advance.
Edit: If this is the way to go, can some specific children override this abstract function?

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.

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(){
...
}
}

Accessing parent methods in 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).

Categories