I am trying to understand one PHP OOP concept, lets say i have two classes A and B. B extends A there fore A is Base/Parent class. If class A has a __construct class B will automatically inherit it...?
Example:
class Car
{
public $model;
public $price;
public function __construct()
{
$this->model = 'BMW';
$this->price = '29,00,00';
}
}
class Engine extends Car
{
parent::__construct();
}
By parent::__construct(); class Engine will execute Car __construct(); automatically?
But I always though if I inherit from parent class the __construct will be executed automatically anyway why would I add this parent::__construct()?
When one class extends another, it inherits all its methods. Yes, that includes the constructor. You can simply do class Engine extends Car {}, and Engine will have a constructor and all other properties and methods defined in Car (unless they're private, which we'll ignore here).
If you define a method of the same name as already exists in Car in Engine, you're overriding that method implementation. That's exactly what it sounds like: instead of Car's implementation, Engine's method is called.
why would I add this parent::__construct()?
If you're overriding a method, yet you also want to call the parent's implementation. E.g.:
class Engine extends Car {
public function __construct() {
parent::__construct();
echo 'Something extra';
}
}
Overriding a constructor in a child class is exactly that, overriding... you're setting a new constructor for the child to replace the parent constructor because you want it to do something different, and generally you won't want it to call the parent constructor as well..... that's why you need to explicitly call the parent constructor from the child constructor if you want them both to be executed.
If you don't create a child constructor, then you're not overriding the parent constructor, so the parent constructor will then be executed
Related
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.
In my PHP code I have a protected method in an abstract class which we'll call class A. If I create a new class called B which extends A, do I have to simply declare it public in B or do I have to re-write all the implementation so when I instanciate B I can then call this method?
abstract class A {
protected function test() {
//do some stuff here
}
}
class B extends A {
public function test() {
//Do I need to do something here?
}
}
Thank you
Crouz
You need to do parent::test() call - or not do not declare method in child class at all. In second case method will be inherited from parent class while in first case it will be method of B which calls parent method, i.e. method of A.
Also, if you will not declare method in child class, it will not be public, so it may be not the thing you're looking for (mentioned to show how inheritance works). I.e. if you want to have public method - the only way would be calling parent::test() from inside test() method of B class
A simple question, does the following make sense ?
Class B extends Class A
class A constructor:
function __construct(){
//do something
}
Class B constructor:
function __construct(){
parent::__construct();
}
Is there any significant advantage to implementing the child constructor at all in this case?
I can only think of :
The entire code for class B will be more "complete" in structure
Would be interesting to know if there is any significant advantages in coding or in structuring etc.
The only time you want to invoke your parent constructor from your subclass (child class) is when you want to add custom code in your constructor.
In your example you can leave out the __construct() method altogether in Class B.
However you might want to do something like this:
class A {
function __construct() {
run_a_function();
$this->set = "a variable";
}
}
class B {
function __construct() {
run_a_function_specific_to_class_b();
$this->set = "a variable specific to class b";
// now call the parent constructor
parent::__construct();
}
}
No. If all your constructor (or any method for that matter) does is call the parent method of the same name, then there's no advantage whatsoever. Just more lines of code.
A local constructor overrides its parent:
<?php
class Blog extends CI_Controller {
public function __construct()
{
parent::__construct();
// Your own constructor code
}
}
?>
If you have a __construct() method in the child class you must call the parent constructor explicitly.
If you have no desire to run anything in the child constructor, do not specify the constructor method in the child and the parents constructor will be called automatically.
If I have the following class:
class foo {
function __construct() {
// Some code
}
}
And then use inheritance to create:
class bar extends foo {
// Some code
}
When I instantiate class 'bar', will it automatically execute the __construct method from 'foo' or do I need to do something else to get that method to execute?
From the manual:
Note: Parent constructors are not
called implicitly if the child class
defines a constructor.
While the documentation doesn't state it explicitly, the inverse of this sentence is also true, i.e., parent constructors are called implicitly if the child class does not define a constructor. Therefore, in your example, instantiating bar would call foo::__construct automatically.
it works, the constructer from the parent class will be inherited.
if you define a new constructor in the instaciated class, it will override the constructor function of the parent class. if you still want to execute the parent constructer you should include
parent::__construct();
in the constructer of thje isntanciated class
The __construct will carry over, yes.
The issue comes when you want to add something to that function, which is when the parent class comes in handy.
class bar extends foo {
$this->doSomethingElse();
parent::__construct();
}
Of course when you extend a class, the subclass inherits all of the public and protected methods from the parent class.
Take this example:
abstract class Base {
function __construct() {
echo 'Base __construct<br/>';
}
}
class Child extends Base {
function __construct() {
echo 'Child __construct<br/>';
}
}
$c = new Child();
Coming from a C# background, I expect the output to be
Base __construct Child __construct
However, the actual output is just
Child __construct
No, the constructor of the parent class is not called if the child class defines a constructor.
From the constructor of your child class, you have to call the constructor of the parent's class :
parent::__construct();
Passing it parameters, if needed.
Generally, you'll do so at the beginning of the constructor of the child class, before any specific code ; which means, in your case, you'd have :
class Child extends Base {
function __construct() {
parent::__construct();
echo 'Child __construct<br/>';
}
}
And, for reference, you can take a look at this page of the PHP manual : Constructors and Destructors -- it states (quoting) :
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.
Well, I just found this in the docs:
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 you need the same behaviour as C#, that is the parent constructor gets always executed before child constructor, you could create a fake constructor class for your child classes and declare it as an abstract function in your abstract parent class.
E.g.
abstract class Test{
abstract public function __childconstruct();
public function __construct(){
echo "SOME CODE".PHP_EOL;
$this->__childconstruct();
}
}
class TestExtended extends Test{
public function __childconstruct(){
echo "SOME OTHER CODE FROM EXTENDED CLASS".PHP_EOL;
}
}
$a = new TestExtended();
/* SOME CODE
SOME OTHER CODE FROM EXTENDED CLASS */