i have two class:
class BaseClass
{
public function __construct()
{
$this->init();
}
private function init()
{
//dosomething
}
}
class Myclass extends BaseClass
{
public function __construct()
{
}
}
now when i create:
$myclass = new Myclass;
function init is not running, somebody can help me?
That is because you are overriding your constructor within your child class. Just leave it out when you are not processing any tasks that differ from your parents constructor or call your parents constructor like that
class Myclass extends BaseClass
{
public function __construct()
{
parent::__construct(); // Call the parents constructor
// Do some stuff that explicitly belongs to the child class
}
}
Let's take a look on what the PHP docs say on it:
Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).
Further reading:
PHP Docs - Constructors and Destructors
Related
I have a base class and I want to have one of its methods called after the extending class is constructed. Ideally this should happen without changing the extended class constructor:
class BaseClass {
protected function doSomethingAfterConstruct() {}
}
class ExtendedClass extends BaseClass {
public function __construct() {
// some custom constructor code
}
}
I could just call $this->doSomethingAfterConstruct() at the end of the ExtendedClass constructor or by calling parent::__construct, but I am looking for a solution where I can implement this behavior by only changing the baseclass.
If it would be not __constructor, but ordinary method, then you can use __call magic method to proxy calls to child class:
All child methods should be non-public visibility, to trigger magic method
class BaseClass {
public function __call($name, $arguments) {
$return = $this->{$name}(...$arguments);
$this->doSomethingAfterMethod();
return $return;
}
protected function doSomethingAfterMethod() {}
}
class ExtendedClass extends BaseClass {
private function randomMethod() {
// some custom method code
}
}
Say I have class child() and class parent(). The parent has a constructor and a few other public methods, and the child is empty apart from a constructor.
How do I go about calling a parent's methods inside of the child's constructor, as in:
Class Parent {
public function __construct() {
// Do stuff (set up a db connection, for example)
}
public function run($someArgument) {
// Manipulation
return $modifiedArgument;
}
}
Class Child extends Parent {
public function __construct() {
// Access parent methods here?
}
}
Say I want to call parents run() method, do I have to call a new instance of the parent inside the child constructor? Like so...
$var = new Parent();
$var->run($someArgument);
If so, what is the point of extends from a class definition POV? I can call a new instance of another class with the new keyword whether it extends the 'child' or not.
My (likely) wrong understanding was that by using extends you can link classes and methods from a parent can be inherited into the child. Is that only outside the class definition? Does using extend offer no efficiencies inside the class definition?
Because referring to the parent's run() method with the this keyword certainly doesn't work...
Use parent as predefined reference: parent::run(). This will ensure you call parent method. The same way you could call first parent constructor first or after child one - parent::__construct().
Class Child extends Parent {
public function __construct() {
parent::__construct();
// Access parent methods here?
$some_arg = NULL; // init from constructor argument or somewhere else
parent::run($some_arg); // explicitly call parent method
// $this->run($some_arg); // implicitly will call parent if no child override
}
}
If you dont have an implementation in child you could call $this->run($args), where it will again call parent run method.
To extend Rolice's answer
function a() {
echo 'I exist everywhere';
}
class A {
protected $a
function a() {
$this->a = 'I have been called';
}
function out() {
echo $this->a;
a();
}
}
class B extends A {
function __construct() {
parent::a();// original method
$this->a(); // overridden method
a();
}
function a() {
$this->a = $this->a ? 'I have been overwritten' : 'first call';
}
}
Study these to understand the difference
My question is concerning the inheritance mechanisms in object oriented PHP. If I want a class variable to be initialized in a super class in its constructor and all children classes to make use of initialized variable, I can't do this in the constructor of the superclass, since the superclasses constructor is not implicitly called by the children classes constructor, as in Java. If I have to manually call the super classes constructor from every children constructor, I do not have any benefit from simply doing the initialization in every children classes constructor.
How can I solve this problem? Any ideas?
class superclass {
protected $a;
function __construct() {
$this->a = new Foo();
}
}
class childrenclass1 extends superclass {
function __construct() {
do_something;
}
function childrenfunction() {
$this->a->method(); // not initalized;
}
}
Like Java, the superclass constructor is only called automatically when the child classes don't implement their own constructor. Alternatively, the initial property values can be declared as part of the class definition if they're a constant expression.
So, basically, your choices are:
Initialize the variable with a non-dynamic value in the parent class:
protected $var = 123;
Use parent::__construct() in all child classes that implement their own constructor. This is still better than initializing those properties in each child class, because using the parent's constructor doesn't duplicate code.
If the inheritance depth is 2 (i.e. only parent and child) you could drop the child constructor and define an initialization method:
class Parent
{
public function __construct()
{
...
$this->initialize();
}
protected function initialize() {}
}
class Child extends Parent
{
protected final function initialize()
{
...
}
}
The benefit to not doing the initialization in every child class constructor is that the logic of what to initialize it to can be kept in a single place - in the parent constructor. Calling the parent constructor from every child constructor can be tedious, but at least it's not duplicating the logic.
Your other option is to make the variable private, and use a method to access it from the child classes. The method can initialize it if needed, and then return the value.
class superclass {
private $a;
protected function getA() {
if (!($this->a instanceof Foo)) {
$this->a = new Foo();
}
return $this->a;
}
}
class childrenclass1 extends superclass {
public function childrenfunction() {
$this->getA()->method();
}
}
...don't forget to access your variable or method using $this. You can't leave that out in PHP like you can in Java.
It's a good practice to call parent constructor because it can initialize some variables or do other usefull things. But if you don't want to write in any child constructor parent::__construct() you can avoid write child constructor and move everything to a special method init. It will look like as:
class A {
public function __construct() {
do smt
}
}
class B extends A {
public function init() {
do smt
}
}
$b = new B();
$b->init();
If I have an abstract class like this:
abstract class MyApp
{
public function init()
{
$this->stuff = $this->getStuff();
}
public function getStuff()
{
return new BlueStuff();
}
}
And then I have a class that extends from this abstract class like this:
class MyExtendedClass extends MyApp
{
public function init()
{
parent::init();
}
public function getStuff()
{
return new RedStuff();
}
}
If I do:
$myobj = new MyExtendedClass();
$myobj->init();
Why does the method getStuff from the child class get called? Isn't $this in the context of the abstract class? If so, shouldn't the method of the abstract class get called?
Thanks!
New answer
In PHP you can use subclasses as if all methods in the parent class that don't exist in the subclass have been copied to the subclass. So your example would be the same as:
class MyExtendedClass extends MyApp {
public function init() {
$this->stuff = $this->getStuff();
}
public function getStuff() {
return new RedStuff();
}
}
Just think of the subclass as having all code of the parent class and you're normally all right. There is one exception to this rule: properties. A private property of a class can only be accessed by that class, subclasses can't access the private properties of parent classes. In order to do that you need to change the private property into a protected property.
Original answer
Abstract classes in PHP are just like regular classes with one big difference: they can't get initiated. This means you can't do new AbstractClass();.
Since they work exactly like regular classes for everything else, this also is the case for extending classes. This means that PHP first tries to find the method in the initiated class, and only looks in the abstract classes if it doesn't exist.
So in your example this would mean that the getStuff() method from MyExtendedClass is called. Furthermore, this means you can leave out the init() method in MyExtendedClass.
I mean something like that:
class parentClass {
public function method() {
echo $this->prop;
}
}
class childClass extends parentClass {
public $prop = 5;
}
How can I get a child prop from the parent prop?
Thanks...
Either I don't fully understand what you want or the solution is as trivial as the following code.
class parentClass {
public function method() {
echo $this->prop;
}
}
class childClass extends parentClass {
public $prop = 5;
}
$object = new childClass();
$object->method();
I mean the child class is extending the base class which means it will also inherit all the methods of its parent's class. That makes the whole process of using the parent's class method as simple as calling it from the instance of the child class.
All protected and public members of child classes are visible from within their parent class in PHP, so the example code you provided should work just fine. Quote from the php doc:
Members declared protected can be accessed only within the class
itself and by inherited and parent classes.
But the actual question is: do you really need it?
The proper OO way would be to define a self-contained parent class that expresses something. It should not need to access properties of child classes - this is a so-called code smell. If you really think that you have a case where a similar construct is necessary, you are probably looking for abstract methods, which guarantee that every child class has this property:
abstract class Animal {
public function makeNoise() {
echo $this->getNoiseString();
}
protected abstract function getNoiseString();
}
class Cat extends Animal {
protected function getNoiseString() {
return 'meow';
}
}
//parent
class parentClass {
protected $prop = null;
public function method() {
echo $this->prop;
}
}
//child
class childClass extends parentClass {
protected $prop = 5;
}
Make sure the variable is defined in the parentclass as well. So it will be accessible by the parent.