PHP: How can I call child methods from the base class? - php

From my understanding, it is good practice to not give a class too many responsibilities and good to split into sub classes, I am new to programming, so my idea was to do the following:
<?php
class ChildClass extends ParentClass
{
public static function child()
{
echo "Child";
}
}
class ParentClass
{
public static function parentF()
{
echo "Parent";
}
}
ParentClass::child();
However, that fails because the Parent does not have access to the child function. From what I am describing, what should I be doing instead? My goal is to learn how to split a big class into multiple to make things easier to maintain.

Classes can only access their parent like you concluded, not the other way around. Extending make the parent functions available in the child.
So what is possible is:
ChildClass::parentF();

Related

How to prevent inheritance of static methods? [duplicate]

So let's say I have classes called parent and child, which will be then used from PHP file called caller.php
class Child extends Parent {
}
class Parent {
public function parentMethod(){
}
}
caller.php
PREVENTED:
$child = new Child();
$child->parentMethod();
ALLOWED:
$parent = new Parent();
$parent->parentMethod();
I want to prevent calling parentMethod like this. But if I created Parent object I want to be able to call the parentMethod. Is there some way that I can use to hide this method from being public in Child class, but still allowing parent object to call this method publicly?
Only solution I have come up with so far is making those methods protected and then creating an other class that would extend parent and then have public method for each function that it needs, but that doesn't sound very smart.
Actually, you should ask yourself: why do you need such restriction? You've defined your method as public - thus, you told PHP that it should be visible everywhere. So to prevent child calls you should use private visibility definition.
There is a way to check if call is made from parent class, like:
class ChildClass extends ParentClass {}
class ParentClass
{
public function parentMethod()
{
if(get_class($this) != __CLASS__)
{
throw new LogicException("Somehow due to business logic you're not allowed to call this from childs");
}
}
}
But I would not recommend to do that. Reasons are:
Readability. Your method is just ordinary public method. Looking to it it's impossible to say either you should use it with child calls or not. Thus, to maintain such code you'll need to check that restriction in code. Now imagine that you have ~50 methods like that. And dozen of classes like that.
Possibly, breaking Law of Demeter. Why should parent class be aware of it's childs when using such limitation?
Finally, it's just unexpected behavior. Looking to definition, anybody will see that you're extending one class by another. Thus, by definition all inherit methods with proper visibility must be inherited. And your logic changes that.
You may think about composition, not inheritance. That may be right way to implement your logic (however, I can't tell that for sure since I don't know whole background)
You can rearrange your code by adding a base parent class for both of your mentioned classes. Like so:
class Base {
public function inheritableMethod1() {}
public function inheritableMethod2() {}
}
class Child extends Base {
}
class Parent extends Base {
public function additionalMethod() {}
}
Move all inheritable methods from the Parent class to the Base, and leave there only those which must not be called on Child (the parentMethod in your example).
The base class optionally might be abstract to prevent instantiating it directly.
Check if Abstract Class suits your needs:
PHP: Class Abstraction
class Child extends Parent {
public function parentMethod(
# Code
}
}
Abstract class Parent {
abstract public function parentMethod();
}

How to prevent usage of public parent methods in child instance in PHP?

So let's say I have classes called parent and child, which will be then used from PHP file called caller.php
class Child extends Parent {
}
class Parent {
public function parentMethod(){
}
}
caller.php
PREVENTED:
$child = new Child();
$child->parentMethod();
ALLOWED:
$parent = new Parent();
$parent->parentMethod();
I want to prevent calling parentMethod like this. But if I created Parent object I want to be able to call the parentMethod. Is there some way that I can use to hide this method from being public in Child class, but still allowing parent object to call this method publicly?
Only solution I have come up with so far is making those methods protected and then creating an other class that would extend parent and then have public method for each function that it needs, but that doesn't sound very smart.
Actually, you should ask yourself: why do you need such restriction? You've defined your method as public - thus, you told PHP that it should be visible everywhere. So to prevent child calls you should use private visibility definition.
There is a way to check if call is made from parent class, like:
class ChildClass extends ParentClass {}
class ParentClass
{
public function parentMethod()
{
if(get_class($this) != __CLASS__)
{
throw new LogicException("Somehow due to business logic you're not allowed to call this from childs");
}
}
}
But I would not recommend to do that. Reasons are:
Readability. Your method is just ordinary public method. Looking to it it's impossible to say either you should use it with child calls or not. Thus, to maintain such code you'll need to check that restriction in code. Now imagine that you have ~50 methods like that. And dozen of classes like that.
Possibly, breaking Law of Demeter. Why should parent class be aware of it's childs when using such limitation?
Finally, it's just unexpected behavior. Looking to definition, anybody will see that you're extending one class by another. Thus, by definition all inherit methods with proper visibility must be inherited. And your logic changes that.
You may think about composition, not inheritance. That may be right way to implement your logic (however, I can't tell that for sure since I don't know whole background)
You can rearrange your code by adding a base parent class for both of your mentioned classes. Like so:
class Base {
public function inheritableMethod1() {}
public function inheritableMethod2() {}
}
class Child extends Base {
}
class Parent extends Base {
public function additionalMethod() {}
}
Move all inheritable methods from the Parent class to the Base, and leave there only those which must not be called on Child (the parentMethod in your example).
The base class optionally might be abstract to prevent instantiating it directly.
Check if Abstract Class suits your needs:
PHP: Class Abstraction
class Child extends Parent {
public function parentMethod(
# Code
}
}
Abstract class Parent {
abstract public function parentMethod();
}

Accessing sibling method

I've been searching for an answer all day, but I can't seem to find one. Sorry if I don't make much sense, I'm losing my mind over this.
Here's what I'm trying to do:
abstract class Parent {
abstract public function Test();
}
class Child1 extends Parent {
abstract public function Test() {
echo "Test!";
}
}
class Child2 extends Parent {
public function Test2() {
echo "Test2!";
$this->Test(); // Child1::Test();
}
}
Again, sorry if I'm not making much sense. I will try to explain more if you need me to.
It's not an OOP pattern, and not available in any OOP language that I kow of (except for introspection magic):
Child2 do not know anything (and does not have to) about Child1 class. they could be defined independently.
I think that at this point you should explain what your needs are. I guess we could help you ,with some design pattern.
You can't. What you're tryning to do has no sense in OOP. If you want to execute Test() from the first Child, you need to move the function in the parent.
EDIT: Well, I'm going to be more comprehensive:
You're trying to call a function of another child, which have only the parent class in common. Child1 and Child2 are as close as String and Integer can be in Java (or any other OOP language). Imagine that you called .upper() function on a int: it doesn't make sense.
There are several things wrong here:
Parent is a reserved word
Child1 contains an abstract method, so it can't contain a body.
Child2 extends Parent, but doesn't implement the Test() method.
As a result, none of this will instantiate. Child2() should probably extend Child1(),(or implement the Test() method itself). Correct these problems, fix any other errors that PHP might tell you about then this:
$p = new Child2();
$p->Test2();
Should give you this:
Test2!Test!
You are missing the concept of abstract classes and methods.
Abstract classes
Abstract classes are classes that define some basic behavior and cannot be instantiated. They are designed to be subclassed.
Abstract methods
These are methods that need to be implemented by the extending class. Like interfaces abstract methods define behavior without an implementation.
Your code
In your code you declared an abstract class with an abstract method.
abstract class Parent {
public abstract function Test();
}
When another class subclasses Parent it must implement the abstract method making it concrete.
class Child extends Parent {
public function Test() {
echo "Test!";
}
}
Accessing sibling method
A class or instance has no concept of a sibling. A class cannot know who subclasses its parent and access it in a static way.
The Test overrided function in Child1 should not be abstract (as you are defining it). To call the Test function of Child1 from the Test2 function of Child2 use:
Child1 foo = new Child1();
echo foo->Test();
Thing you can do only because it's been defined as public, not because Child1 and Child2 have any relationship.

Child class properties populated with parent class methods

I am new to PHP and just get into OOP. I have few generic methods used to set and get properties. I use them quite often in almost all the classes, i put those methods in a class and extends other classes from it. Now i can access the methods from child class but dont know how set and get attributes of child class through them ... parent class base.php
class Base
{
public function __construct()
{
}
function __set($propName, $propValue)
{
$this->$propName = $propValue;
}
function setProperties(array $data)
{
foreach($data as $propName => $propValue)
$this->$propName = $propValue;
}
function __get($propName)
{
return (isset($this->$propName))? $this->$propName : "Invalid property!";
}
function getProperties(array $properties)
{
foreach($properties as $propName)
$propVals[$propName] = $this->$propName;
return $propVals;
}
}
child class categories.php
class categories extends Base
{
private $id;
private $pid;
private $title;
private $status;
public function __construct()
{
parent::__construct();
}
}
and i called it like
$objCat = new categories();
$objCat->setProperties(array('id'=>'10', 'pid'=>'6'));
print_r( $objCat->getProperties(array('id', 'pid')));
Need little guidance here. If its the right way? or at least is it possible to do it like this? if so how to accomplish this ...
thanks
Extending a class is something you only want to do when you can say class categories is a class Base. Something like that sort of utility class you have their is almost always the wrong way to go. PHP also has introduced something called traits for copy/paste code. However my personal preference is that it is something you will never want to use, because it tightly couples the traits to your class, which is something you want to avoid.
See for more information the Liskov Substitution principle in SOLID programming.
If it was up to me I would avoid those magic getters / setters either way and just add your own getters / setters methods to the class.
The mistake about some base class isn't something only you are doing (hell even I have done it in the past). Think about some class Database and a class Article. Because the Article class needs access to the database many people let the class extend the Database class. This isn't correct because an article isn't an database. Instead an instance of the database class should be injected into the article class by using dependency injection. The instance should either be injected into the class constructor (if all or many methods need access to it) or just the methods that need it. So when extending a class you have to be able to say class B is a class A.
Some other notes about your code:
Always make your class names PascalCase. This is not really required to make your code work, but it follows a naming convention often used.
And my personal preference a bit: please always add curly braces to your foreach statements. It is more clear what is happening when other people are reading your code.

PHP Import Foreign Class' Method into MyClass

Wondering if this is possible in PHP Land:
Let's say I have a class as follows:
class myClass{
var $myVar;
...
myMethod(){
$this->myVar = 10;
}
}
and another class:
class anotherClass {
...
addFive(){
$this->myVar += 5;
}
}
The 'anotherClass' is 3500 lines long and I just want the single 'addFive' method to use in myClass.
Is there a way I can import the function and be able to call it in my class and the $this would reference the myClass object?
Is this good/bad practice?
(optional) How does this work in Python? (Just curious as I'm starting to learn Python)
The easiest way to do this is have one class extend the other
class myClass extends anotherClass {
}
The myClass class now has access to all the methods of anotherClass that are public or protected.
If you only want the class to have one method of the other, or it's not practical to have one class extends from the other, there's nothing built into PHP that will allow you to do this. The concept you're looking to Google for is "Mixin", as in Mix In one class's functionality with another. There's an article or two on some patterns you could try to achieve this functionality in PHP, but I've never tried it myself.
Good idea/Bad Idea? Once you have the technique down it's convenient and useful, but costs you in performance and makes it harder for a newcomer to grok what you're doing with your code, especially (but not limited to) someone less familiar with OO concepts.
A better approach would be to move the complex method into its own class. Then both of your classes can instantiate it, pass any necessary data, and call the method.
If your myClass extends anotherClass it inherits all the methods and properties of anotherClass (except those marked private).
class AnotherClass {
protected $myVar;
public function addFive(){
$this->myVar += 5;
}
}
class MyClass extends AnotherClass {
public function __construct() {
$this->myVar = 0;
}
public function myMethod(){
$this->myVar = 10;
}
}
$m = new MyClass;
$m->myMethod();
$m->addFive();
var_dump($m);
prints
object(MyClass)#1 (1) {
["myVar":protected]=>
int(15)
}

Categories